diff --git a/scantool/diag.h b/scantool/diag.h index b798588c..5236e271 100644 --- a/scantool/diag.h +++ b/scantool/diag.h @@ -33,63 +33,69 @@ extern "C" { #include "cconf.h" +#include "diag_os.h" // For mutexes. + #ifdef WIN32 - #ifndef _WIN32_WINNT - #define _WIN32_WINNT 0x0500 //use > winXP features... - #endif - #include - #include - #include +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0500 // use > winXP features... +# endif +# include +# include +# include #else - #include +# include #endif #include -#include /* For uint8_t, etc. This is a C99 header */ -#include /* For FILE */ +#include /* For uint8_t, etc. This is a C99 header */ +#include /* For FILE */ // Nice to have anywhere... #define MIN(_a_, _b_) (((_a_) < (_b_) ? (_a_) : (_b_))) -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -#define FLFMT "%s:%d: " //for debug messages - - -#ifndef HAVE_STRCASECMP //strcasecmp is POSIX, but kernel32 provides lstrcmpi which should be equivalent. -#ifdef WIN32 - #define strcasecmp(a,b) lstrcmpi((LPCTSTR) a, (LPCTSTR) b) -#else - #error Your system provides no strcasecmp ! This is a problem ! -#endif //WIN32 -#endif //have_strcasecmp - +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define FLFMT "%s:%d: " // for debug messages -#define DB_FILE "./freediag_carsim_all.db" //default simfile for CARSIM interface -#define DIAG_NAMELEN 256 +#ifndef HAVE_STRCASECMP // strcasecmp is POSIX, but kernel32 provides lstrcmpi which should + // be equivalent. +# ifdef WIN32 +# define strcasecmp(a, b) lstrcmpi((LPCTSTR)a, (LPCTSTR)b) +# else +# error Your system provides no strcasecmp ! This is a problem ! +# endif // WIN32 +#endif // have_strcasecmp +#define DB_FILE "./freediag_carsim_all.db" // default simfile for CARSIM interface +#define DIAG_NAMELEN 256 /****** compiler-specific tweaks ******/ #ifdef __GNUC__ - #define UNUSED(X) X __attribute__((unused)) //magic ! +# define UNUSED(X) X __attribute__((unused)) // magic ! #else - #define UNUSED(X) X //how can we suppress "unused parameter" warnings on other compilers? -#endif // __GNUC__ +# define UNUSED(X) \ + X // how can we suppress "unused parameter" warnings on other compilers? +#endif // __GNUC__ -//hacks for MS Visual studio / visual C +// hacks for MS Visual studio / visual C #ifdef MSVC - typedef SSIZE_T ssize_t; //XXX ssize_t is currently only needed because of diag_tty_unix.c:diag_tty_{read,write}. - //TODO : rework read/write types to use a combination of size_t and int ? - #define snprintf _snprintf //danger : _snprintf doesn't guarantee zero-termination !? - #pragma message("Warning: MSVC _sprintf() may be dangerous !\ +typedef SSIZE_T ssize_t; // XXX ssize_t is currently only needed because of + // diag_tty_unix.c:diag_tty_{read,write}. + // TODO : rework read/write types to use a combination of size_t + // and int ? +# define snprintf \ + _snprintf // danger : _snprintf doesn't guarantee zero-termination !? +# pragma message( \ + "Warning: MSVC _sprintf() may be dangerous !\ Please ask your compiler vendor to supply a C99-compliant snprintf()...") - //CURFILE will be defined by CMake on a per-file basis ! - #pragma message("Warning: MSVC may not work with the CURFILE macro. See diag.h") - // apparently some (all ?) MSVC compilers don't support per-file defines, so CURFILE would be the - // same for all source files. - // The disadvantage of __FILE__ is that it often (always ?) holds the absolute path of the file, - // not just the filename. For our debugging messages we only care about the filename, hence CURFILE. - #define CURFILE __FILE__ +// CURFILE will be defined by CMake on a per-file basis ! +# pragma message("Warning: MSVC may not work with the CURFILE macro. See diag.h") +// apparently some (all ?) MSVC compilers don't support per-file defines, so +// CURFILE would be the same for all source files. The disadvantage of __FILE__ is +// that it often (always ?) holds the absolute path of the file, not just the +// filename. For our debugging messages we only care about the filename, hence +// CURFILE. +# define CURFILE __FILE__ #else - #define FL CURFILE, __LINE__ +# define FL CURFILE, __LINE__ #endif /****** ******/ @@ -99,11 +105,11 @@ extern "C" { */ #define MAXRBUF 1024 -#define DIAG_MAX_MSGLEN 4200 /** limit diag_allocmsg() message size. */ +#define DIAG_MAX_MSGLEN 4200 /** limit diag_allocmsg() message size. */ typedef uint8_t target_type, source_type, databyte_type, command_type; -typedef uint16_t flag_type; //this is used for L2 type flags (see diag_l2.h) - //only used for diag_l2_startcomms() arg +typedef uint16_t flag_type; // this is used for L2 type flags (see diag_l2.h) + // only used for diag_l2_startcomms() arg /* * IOCTLs @@ -115,63 +121,68 @@ typedef uint16_t flag_type; //this is used for L2 type flags (see diag_l2.h) * XXX Are their numeric values chosen on purpose ? i.e. why "2023" etc. */ -#define DIAG_IOCTL_GET_L1_TYPE 0x2010 /* Get L1 Type, data is ptr to int */ -#define DIAG_IOCTL_GET_L1_FLAGS 0x2011 /* Get L1 Flags, data is ptr to int */ -#define DIAG_IOCTL_GET_L2_FLAGS 0x2021 /* Get the L2 flags (see fmt stuff )*/ -#define DIAG_IOCTL_GET_L2_DATA 0x2023 /* Get the L2 Keybytes etc into - * diag_l2_data passed to us - */ -#define DIAG_IOCTL_SETSPEED 0x2101 /* Set speed, bits etc. data = (const struct diag_serial_settings *); ret 0 if ok - * Ignored if DIAG_L1_AUTOSPEED or DIAG_L1_NOTTY is set */ -#define DIAG_IOCTL_INITBUS 0x2201 /* Initialise the ecu bus, data = (struct diag_l1_initbus_args *) - * - * Caller must have waited the appropriate time before calling this, since any - * bus-idle requirements are specified at the L2 level. - * Must return as soon as possible, - * and restore original port settings (speed, etc). - * See diag_l1.h for initbus args - * return 0 if ok - */ -#define DIAG_IOCTL_IFLUSH 0x2202 /* flush input buffers. No data. Ignored if DIAG_L1_NOTTY is set. - * Ret 0 if ok / not applicable (non fatal error) */ +#define DIAG_IOCTL_GET_L1_TYPE 0x2010 /* Get L1 Type, data is ptr to int */ +#define DIAG_IOCTL_GET_L1_FLAGS 0x2011 /* Get L1 Flags, data is ptr to int */ +#define DIAG_IOCTL_GET_L2_FLAGS 0x2021 /* Get the L2 flags (see fmt stuff )*/ +#define DIAG_IOCTL_GET_L2_DATA \ + 0x2023 /* Get the L2 Keybytes etc into \ + * diag_l2_data passed to us \ + */ +#define DIAG_IOCTL_SETSPEED \ + 0x2101 /* Set speed, bits etc. data = (const struct diag_serial_settings *); ret \ + * 0 if ok Ignored if DIAG_L1_AUTOSPEED or DIAG_L1_NOTTY is set */ +#define DIAG_IOCTL_INITBUS \ + 0x2201 /* Initialise the ecu bus, data = (struct diag_l1_initbus_args *) \ + * \ + * Caller must have waited the appropriate time before calling this, since \ + * any bus-idle requirements are specified at the L2 level. Must return as \ + * soon as possible, and restore original port settings (speed, etc). See \ + * diag_l1.h for initbus args return 0 if ok \ + */ +#define DIAG_IOCTL_IFLUSH \ + 0x2202 /* flush input buffers. No data. Ignored if DIAG_L1_NOTTY is set. \ + * Ret 0 if ok / not applicable (non fatal error) */ /** Set wake-up (keepalive) message. * Only applicable if DIAG_L1_DOESKEEPALIVE is set * * data = (struct diag_msg *). * The (struct diag_msg)->data member must be a raw message (including headers) * - * data can be freed by caller after the ioctl (L0 will make a copy of the message data as required) + * data can be freed by caller after the ioctl (L0 will make a copy of the message data as + * required) */ #define DIAG_IOCTL_SETWM 0x2203 /****** debug control ******/ -// flag containers : diag_l0_debug, diag_l1_debug diag_l2_debug, diag_l3_debug, diag_cli_debug - -#define DIAG_DEBUG_OPEN 0x01 /* Open events */ -#define DIAG_DEBUG_CLOSE 0x02 /* Close events */ -#define DIAG_DEBUG_READ 0x04 /* Read events */ -#define DIAG_DEBUG_WRITE 0x08 /* Write events */ -#define DIAG_DEBUG_IOCTL 0x10 /* Ioctl stuff (setspeed etc) */ -#define DIAG_DEBUG_PROTO 0x20 /* Other protocol stuff */ -#define DIAG_DEBUG_INIT 0x40 /* Initialisation stuff */ -#define DIAG_DEBUG_DATA 0x80 /* Dump data depending on other flags */ -#define DIAG_DEBUG_TIMER 0x100 /* Timer stuff */ - -enum debugflag_enum {OPEN=DIAG_DEBUG_OPEN, - CLOSE=DIAG_DEBUG_CLOSE, - READ=DIAG_DEBUG_READ, - WRITE=DIAG_DEBUG_WRITE, - IOCTL=DIAG_DEBUG_IOCTL, - PROTO=DIAG_DEBUG_PROTO, - INIT=DIAG_DEBUG_INIT, - DATA=DIAG_DEBUG_DATA, - TIMER=DIAG_DEBUG_TIMER, - NIL=0 +// flag containers : diag_l0_debug, diag_l1_debug diag_l2_debug, diag_l3_debug, +// diag_cli_debug + +#define DIAG_DEBUG_OPEN 0x01 /* Open events */ +#define DIAG_DEBUG_CLOSE 0x02 /* Close events */ +#define DIAG_DEBUG_READ 0x04 /* Read events */ +#define DIAG_DEBUG_WRITE 0x08 /* Write events */ +#define DIAG_DEBUG_IOCTL 0x10 /* Ioctl stuff (setspeed etc) */ +#define DIAG_DEBUG_PROTO 0x20 /* Other protocol stuff */ +#define DIAG_DEBUG_INIT 0x40 /* Initialisation stuff */ +#define DIAG_DEBUG_DATA 0x80 /* Dump data depending on other flags */ +#define DIAG_DEBUG_TIMER 0x100 /* Timer stuff */ + +enum debugflag_enum { + OPEN = DIAG_DEBUG_OPEN, + CLOSE = DIAG_DEBUG_CLOSE, + READ = DIAG_DEBUG_READ, + WRITE = DIAG_DEBUG_WRITE, + IOCTL = DIAG_DEBUG_IOCTL, + PROTO = DIAG_DEBUG_PROTO, + INIT = DIAG_DEBUG_INIT, + DATA = DIAG_DEBUG_DATA, + TIMER = DIAG_DEBUG_TIMER, + NIL = 0 }; // struct debugflags_descr : filled + used in scantool_debug.c struct debugflags_descr { enum debugflag_enum mask; - const char *descr; //associate short description for each flag. + const char *descr; // associate short description for each flag. const char *shortdescr; }; @@ -183,32 +194,35 @@ struct debugflags_descr { * * The receiver of the message *must* copy the data if it wants it !!! * The flags are arranged such as zeroing out the whole structure sets "safe" defaults. - * There's probably no application for 0-length messages, but currently the various functions - * don't complain when allocating/duplicating empty data. + * There's probably no application for 0-length messages, but currently the various + * functions don't complain when allocating/duplicating empty data. */ struct diag_msg { - uint8_t fmt; /* Message format (doesn't absolutely need to be uint8_t) : */ - #define DIAG_FMT_ISO_FUNCADDR 0x01 /* ISO Functional addressing (default : phys) */ - #define DIAG_FMT_FRAMED 0x02 /* Rcvd data is framed, ie not raw. XXX DEPRECATED ! L0..L2 all do this.*/ -// #define DIAG_FMT_DATAONLY 0x04 /* Rcvd data had L2/L3 headers removed XXX ALWAYS ! */ - #define DIAG_FMT_CKSUMMED 0x08 /* Someone (L1/L2) checked the checksum */ - #define DIAG_FMT_BADCS 0x10 // message has bad checksum - - uint8_t type; /* Type from received frame */ - uint8_t dest; /* Destination from received frame */ - uint8_t src; /* Source from received frame */ - - unsigned len; /* calculated data length */ - uint8_t *data; /* The data; can be dynamically alloc'ed */ - - unsigned long rxtime; /* Processing timestamp, in ms given by diag_os_getms() */ - struct diag_msg *next; /* For linked lists of messages */ - - uint8_t *idata; /* For free() of data later: this is a "backup" - * of the initial *data pointer.*/ - uint8_t iflags; /* Internal flags */ - #define DIAG_MSG_IFLAG_MALLOC 1 /* We malloced; we Free -- this is set when the msg - * was created by diag_allocmsg()*/ + uint8_t fmt; /* Message format (doesn't absolutely need to be uint8_t) : */ +#define DIAG_FMT_ISO_FUNCADDR 0x01 /* ISO Functional addressing (default : phys) */ +#define DIAG_FMT_FRAMED \ + 0x02 /* Rcvd data is framed, ie not raw. XXX DEPRECATED ! L0..L2 all do this.*/ + // #define DIAG_FMT_DATAONLY 0x04 /* Rcvd data had L2/L3 headers + // removed XXX ALWAYS ! */ +#define DIAG_FMT_CKSUMMED 0x08 /* Someone (L1/L2) checked the checksum */ +#define DIAG_FMT_BADCS 0x10 // message has bad checksum + + uint8_t type; /* Type from received frame */ + uint8_t dest; /* Destination from received frame */ + uint8_t src; /* Source from received frame */ + + unsigned len; /* calculated data length */ + uint8_t *data; /* The data; can be dynamically alloc'ed */ + + unsigned long rxtime; /* Processing timestamp, in ms given by diag_os_getms() */ + struct diag_msg *next; /* For linked lists of messages */ + + uint8_t *idata; /* For free() of data later: this is a "backup" + * of the initial *data pointer.*/ + uint8_t iflags; /* Internal flags */ +#define DIAG_MSG_IFLAG_MALLOC \ + 1 /* We malloced; we Free -- this is set when the msg \ + * was created by diag_allocmsg()*/ }; /** Allocate a new diag_msg @@ -217,16 +231,16 @@ struct diag_msg { * @param datalen: if \>0, size of data buffer to allocate. Max DIAG_MAX_MSGLEN. * @return new struct diag_msg, must be freed with diag_freemsg(). */ -struct diag_msg *diag_allocmsg(size_t datalen); +struct diag_msg *diag_allocmsg(size_t datalen); /** Duplicate a diag_msg, including all chained messages and their contents. * @return new struct diag_msg, must be freed with diag_freemsg(). */ -struct diag_msg *diag_dupmsg(struct diag_msg *); +struct diag_msg *diag_dupmsg(struct diag_msg *); /** Duplicate a single diag_msg, without following the linked-list chain. * @return new struct diag_msg, must be freed with diag_freemsg(). */ -struct diag_msg *diag_dupsinglemsg(struct diag_msg *); +struct diag_msg *diag_dupsinglemsg(struct diag_msg *); /** Free a diag_msg * Safe to call with NULL arg @@ -239,16 +253,15 @@ void diag_freemsg(struct diag_msg *); */ uint8_t diag_cks1(const uint8_t *data, unsigned int len); - void diag_printmsg_header(FILE *fp, struct diag_msg *msg, bool timestamp, int msgnum); void diag_printmsg(FILE *fp, struct diag_msg *msg, bool timestamp); /* * General functions */ -//diag_init : ret 0 if ok; +// diag_init : ret 0 if ok; int diag_init(void); -//diag_end : must be called before exiting. Ret 0 if ok +// diag_end : must be called before exiting. Ret 0 if ok int diag_end(void); /** Print bytes in hex format @@ -259,8 +272,8 @@ int diag_end(void); */ void diag_data_dump(FILE *out, const void *data, size_t len); -//smartcat : only verifies if s1 is not too large ! -void smartcat(char *p1, const size_t s1, const char *p2 ); +// smartcat : only verifies if s1 is not too large ! +void smartcat(char *p1, const size_t s1, const char *p2); /* * Error functions. @@ -294,8 +307,8 @@ const char *diag_errlookup(const int code); */ // Do not call directly. -int diag_fl_alloc(const char *fName, const int line, - void **pp, size_t n, size_t s, bool allocIsCalloc); +int diag_fl_alloc(const char *fName, const int line, void **pp, size_t n, size_t s, + bool allocIsCalloc); /** calloc() with logging (clears data) * @param P: *ptr @@ -303,28 +316,53 @@ int diag_fl_alloc(const char *fName, const int line, * @note there is no size argument - it gets it directly * using sizeof. This makes it a little unusual, but reduces potential errors. */ -#define diag_calloc(P, N) diag_fl_alloc(CURFILE, __LINE__, \ - ((void **)(P)), (N), sizeof(**(P)), true) +#define diag_calloc(P, N) \ + diag_fl_alloc(CURFILE, __LINE__, ((void **)(P)), (N), sizeof(**(P)), true) /** malloc() with logging. * Same as diag_calloc, but without clearing. */ -#define diag_malloc(P, N) diag_fl_alloc(CURFILE, __LINE__, \ - ((void **)(P)), (N), sizeof(**(P)), false) +#define diag_malloc(P, N) \ + diag_fl_alloc(CURFILE, __LINE__, ((void **)(P)), (N), sizeof(**(P)), false) /** Add a string to array-of-strings (argv style) -* @param elems: number of elements already in table -* @return new table ptr, NULL if failed -*/ + * @param elems: number of elements already in table + * @return new table ptr, NULL if failed + */ char **strlist_add(char **list, const char *news, int elems); /** Free argv-style string list -* @param elems: number of strings in list -*/ + * @param elems: number of strings in list + */ void strlist_free(char **slist, int elems); +// Atomics + +// Atomically accessed types +typedef struct { + diag_mtx mtx; + bool v; +} diag_atomic_bool; +typedef struct { + diag_mtx mtx; + int v; +} diag_atomic_int; + +#define DIAG_ATOMIC_STATICALLY_DECL_INIT(V) V = {LOCK_INITIALIZER, 0}; +#define DIAG_ATOMIC_INITSTATIC(V) diag_os_initstaticmtx(&((V)->mtx)) +#define DIAG_ATOMIC_DEL(V) diag_os_delmtx(&((V)->mtx)) + +void diag_atomic_store_bool(diag_atomic_bool *a, bool d); +void diag_atomic_store_int(diag_atomic_int *a, int d); +bool diag_atomic_load_bool(diag_atomic_bool *a); +int diag_atomic_load_int(diag_atomic_int *a); + +// Returns true if the periodic timer is no longer necessary, ie. if the diag_end has been +// run. Returns false otherwise. +bool periodic_done(void); + #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_H_ */ diff --git a/scantool/diag_cfg.c b/scantool/diag_cfg.c index e93b9207..69c4fab1 100644 --- a/scantool/diag_cfg.c +++ b/scantool/diag_cfg.c @@ -7,43 +7,44 @@ * */ - #include "diag.h" #include "diag_cfg.h" #include "diag_err.h" -#include "diag_tty.h" //for diag_tty_getportlist() +#include "diag_tty.h" //for diag_tty_getportlist() #include #include #include #include -static const char tty_descr[]="Serial/tty port, such as \"/dev/ttyS0\" or \"\\\\.\\COM11\""; -static const char tty_sn[]="port"; /** tty cfg shortname */ -static const char tty_def[]="/dev/null"; /** last resort fallback */ +static const char tty_descr[] = + "Serial/tty port, such as \"/dev/ttyS0\" or \"\\\\.\\COM11\""; +static const char tty_sn[] = "port"; /** tty cfg shortname */ +static const char tty_def[] = "/dev/null"; /** last resort fallback */ /* top decls */ void optarray_clear(struct cfgi *cfgp); - -//Optional func to refresh opt[] and numopts (for tty, J2534, etc), doesn't change *val -void diag_cfg_refresh(struct cfgi *cfgp) { +// Optional func to refresh opt[] and numopts (for tty, J2534, etc), doesn't change *val +void +diag_cfg_refresh(struct cfgi *cfgp) { if (cfgp->refresh) { cfgp->refresh(cfgp); } return; } -//Optional: func to reset *val to default; doesn't call refresh() -void diag_cfg_reset(struct cfgi *cfgp) { +// Optional: func to reset *val to default; doesn't call refresh() +void +diag_cfg_reset(struct cfgi *cfgp) { if (cfgp->reset) { cfgp->reset(cfgp); } return; } - -int diag_cfg_setstr(struct cfgi *cfgp, const char *str) { +int +diag_cfg_setstr(struct cfgi *cfgp, const char *str) { size_t slen; int rv; @@ -51,23 +52,23 @@ int diag_cfg_setstr(struct cfgi *cfgp, const char *str) { return diag_iseterr(DIAG_ERR_BADCFG); } - slen=strlen(str); + slen = strlen(str); if (cfgp->dyn_val && (cfgp->val.str != NULL)) { free(cfgp->val.str); cfgp->val.str = NULL; } - rv = diag_malloc(&cfgp->val.str, slen+1); + rv = diag_malloc(&cfgp->val.str, slen + 1); if (rv != 0) { return diag_iseterr(rv); } - cfgp->dyn_val = 1; //need to free + cfgp->dyn_val = 1; // need to free strcpy(cfgp->val.str, str); return 0; - } -//set config value for a BOOL param -int diag_cfg_setbool(struct cfgi *cfgp, bool val) { +// set config value for a BOOL param +int +diag_cfg_setbool(struct cfgi *cfgp, bool val) { if (cfgp->type == CFGT_BOOL) { cfgp->val.b = val; return 0; @@ -76,7 +77,8 @@ int diag_cfg_setbool(struct cfgi *cfgp, bool val) { } // -int diag_cfg_setu8(struct cfgi *cfgp, uint8_t val) { +int +diag_cfg_setu8(struct cfgi *cfgp, uint8_t val) { if (cfgp->type == CFGT_U8) { cfgp->val.u8 = val; return 0; @@ -84,7 +86,8 @@ int diag_cfg_setu8(struct cfgi *cfgp, uint8_t val) { return diag_iseterr(DIAG_ERR_BADCFG); } -int diag_cfg_setint(struct cfgi *cfgp, int val) { +int +diag_cfg_setint(struct cfgi *cfgp, int val) { if (cfgp->type == CFGT_INT) { cfgp->val.i = val; return 0; @@ -92,8 +95,9 @@ int diag_cfg_setint(struct cfgi *cfgp, int val) { return diag_iseterr(DIAG_ERR_BADCFG); } -//set config value to one of the predefined options. Ret 0 if ok -int diag_cfg_setopt(struct cfgi *cfgp, int optid) { +// set config value to one of the predefined options. Ret 0 if ok +int +diag_cfg_setopt(struct cfgi *cfgp, int optid) { if (optid > (cfgp->numopts - 1)) { return diag_iseterr(DIAG_ERR_BADCFG); } @@ -108,7 +112,7 @@ int diag_cfg_setopt(struct cfgi *cfgp, int optid) { case CFGT_INT: cfgp->val.i = optid; break; - case CFGT_U8: //these don't really make sense + case CFGT_U8: // these don't really make sense case CFGT_BOOL: default: return diag_iseterr(DIAG_ERR_BADCFG); @@ -117,29 +121,30 @@ int diag_cfg_setopt(struct cfgi *cfgp, int optid) { return 0; } -//directly set param value (caller knows correct type and handles mem management, etc) BAD -//void diag_cfg_setraw(struct cfgi *cfgp, void *val) {} +// directly set param value (caller knows correct type and handles mem management, etc) BAD +// void diag_cfg_setraw(struct cfgi *cfgp, void *val) {} -//get param value, as new string to be free'd by caller. -//for u8 / int types, sprintf with %X and %d formatters respectively -char *diag_cfg_getstr(struct cfgi *cfgp) { +// get param value, as new string to be free'd by caller. +// for u8 / int types, sprintf with %X and %d formatters respectively +char * +diag_cfg_getstr(struct cfgi *cfgp) { char *str; const char *fmt; size_t len; int rv; switch (cfgp->type) { case CFGT_U8: - len=5; - fmt="0x%02X"; + len = 5; + fmt = "0x%02X"; break; case CFGT_INT: - //handle 5 digits. - len=6; - fmt="%5d"; + // handle 5 digits. + len = 6; + fmt = "%5d"; break; case CFGT_STR: - len=strlen(cfgp->val.str)+1; - fmt="%s"; + len = strlen(cfgp->val.str) + 1; + fmt = "%s"; break; default: return diag_pseterr(DIAG_ERR_BADCFG); @@ -155,8 +160,9 @@ char *diag_cfg_getstr(struct cfgi *cfgp) { return str; } -//free contents of *cfgp (prior to free'ing the struct itself, for instance) -void diag_cfg_clear(struct cfgi *cfgp) { +// free contents of *cfgp (prior to free'ing the struct itself, for instance) +void +diag_cfg_clear(struct cfgi *cfgp) { /* For now, handles only CFGT_STR types */ if (cfgp->type != CFGT_STR) { return; @@ -165,7 +171,7 @@ void diag_cfg_clear(struct cfgi *cfgp) { free(cfgp->val.str); } cfgp->dyn_val = 0; - cfgp->val.str=NULL; + cfgp->val.str = NULL; optarray_clear(cfgp); @@ -173,25 +179,26 @@ void diag_cfg_clear(struct cfgi *cfgp) { free(cfgp->dval.str); } cfgp->dyn_dval = 0; - cfgp->dval.str=NULL; + cfgp->dval.str = NULL; } - /*** struct management funcs ***/ -//clear / free ->opt[] array -void optarray_clear(struct cfgi *cfgp) { +// clear / free ->opt[] array +void +optarray_clear(struct cfgi *cfgp) { if (cfgp->dyn_opt && (cfgp->opt != NULL)) { /* Need to free every string, and the array of string ptrs */ strlist_free(cfgp->opt, cfgp->numopts); } cfgp->dyn_opt = 0; - cfgp->opt=NULL; + cfgp->opt = NULL; cfgp->numopts = 0; } -//stock reset() function -void std_reset(struct cfgi *cfgp) { +// stock reset() function +void +std_reset(struct cfgi *cfgp) { switch (cfgp->type) { case CFGT_U8: cfgp->val.b = cfgp->dval.b; @@ -217,13 +224,13 @@ void std_reset(struct cfgi *cfgp) { } } - /** Refresh list of known ports * * Keep current port; update default. * If no ports are found, changes nothing */ -void tty_refresh(struct cfgi *cfgp) { +void +tty_refresh(struct cfgi *cfgp) { optarray_clear(cfgp); @@ -236,18 +243,20 @@ void tty_refresh(struct cfgi *cfgp) { /* Update default port */ cfgp->dyn_dval = 1; - if (diag_malloc(&cfgp->dval.str, strlen(cfgp->opt[0])+1)) { + if (diag_malloc(&cfgp->dval.str, strlen(cfgp->opt[0]) + 1)) { optarray_clear(cfgp); return; } - strcpy(cfgp->dval.str, cfgp->opt[0]); //we just used strlen; strcpy is just as dangerous... + strcpy(cfgp->dval.str, cfgp->opt[0]); // we just used strlen; strcpy is just as + // dangerous... cfgp->dyn_opt = 1; return; } -//new TTY / serial port config item -int diag_cfgn_tty(struct cfgi *cfgp) { +// new TTY / serial port config item +int +diag_cfgn_tty(struct cfgi *cfgp) { int rv = diag_cfgn_str(cfgp, tty_def, tty_descr, tty_sn); if (rv != 0) { return rv; @@ -261,13 +270,14 @@ int diag_cfgn_tty(struct cfgi *cfgp) { /** generic types **/ -//ordinary int param using caller's val, and def as default value for reset(). -//Doesn't fill descr and shortname -int diag_cfgn_int(struct cfgi *cfgp, int val, int def) { - cfgp->dyn_val = 0; //caller-supplied +// ordinary int param using caller's val, and def as default value for reset(). +// Doesn't fill descr and shortname +int +diag_cfgn_int(struct cfgi *cfgp, int val, int def) { + cfgp->dyn_val = 0; // caller-supplied cfgp->dyn_dval = 0; cfgp->type = CFGT_INT; - cfgp->numopts=0; + cfgp->numopts = 0; cfgp->dval.i = def; cfgp->val.i = val; cfgp->refresh = NULL; @@ -275,13 +285,14 @@ int diag_cfgn_int(struct cfgi *cfgp, int val, int def) { return 0; } -//ordinary u8 param (copy of _int code) using caller's &val, and *dev as default value for reset(). -//Doesn't fill descr and shortname -int diag_cfgn_u8(struct cfgi *cfgp, uint8_t val, uint8_t def) { - cfgp->dyn_val = 0; //managed by caller +// ordinary u8 param (copy of _int code) using caller's &val, and *dev as default value for +// reset(). Doesn't fill descr and shortname +int +diag_cfgn_u8(struct cfgi *cfgp, uint8_t val, uint8_t def) { + cfgp->dyn_val = 0; // managed by caller cfgp->dyn_dval = 0; cfgp->type = CFGT_U8; - cfgp->numopts=0; + cfgp->numopts = 0; cfgp->val.u8 = val; cfgp->dval.u8 = def; cfgp->refresh = NULL; @@ -289,12 +300,13 @@ int diag_cfgn_u8(struct cfgi *cfgp, uint8_t val, uint8_t def) { return 0; } -//ordinary bool (copy of _int code) -int diag_cfgn_bool(struct cfgi *cfgp, bool val, bool def) { - cfgp->dyn_val = 0; //managed by caller +// ordinary bool (copy of _int code) +int +diag_cfgn_bool(struct cfgi *cfgp, bool val, bool def) { + cfgp->dyn_val = 0; // managed by caller cfgp->dyn_dval = 0; cfgp->type = CFGT_BOOL; - cfgp->numopts=0; + cfgp->numopts = 0; cfgp->val.b = val; cfgp->dval.b = def; cfgp->refresh = NULL; @@ -302,19 +314,20 @@ int diag_cfgn_bool(struct cfgi *cfgp, bool val, bool def) { return 0; } -//ordinary string, copies *def for its default value; sets descr and shortname ptrs -int diag_cfgn_str(struct cfgi *cfgp, const char *def, const char *descr, const char *sn) { +// ordinary string, copies *def for its default value; sets descr and shortname ptrs +int +diag_cfgn_str(struct cfgi *cfgp, const char *def, const char *descr, const char *sn) { char *val, *dval; int rv; assert(def && descr && sn); cfgp->type = CFGT_STR; - rv = diag_malloc(&dval, strlen(def)+1); + rv = diag_malloc(&dval, strlen(def) + 1); if (rv != 0) { return diag_iseterr(rv); } - rv = diag_malloc(&val, strlen(def)+1); + rv = diag_malloc(&val, strlen(def) + 1); if (rv != 0) { free(dval); return diag_iseterr(rv); @@ -322,11 +335,11 @@ int diag_cfgn_str(struct cfgi *cfgp, const char *def, const char *descr, const c cfgp->dval.str = dval; cfgp->dyn_dval = 1; - strcpy(dval, def); //danger + strcpy(dval, def); // danger cfgp->val.str = val; cfgp->dyn_val = 1; - strcpy(val, def); //danger + strcpy(val, def); // danger cfgp->descr = descr; cfgp->shortname = sn; @@ -335,4 +348,3 @@ int diag_cfgn_str(struct cfgi *cfgp, const char *def, const char *descr, const c cfgp->reset = &std_reset; return 0; } - diff --git a/scantool/diag_cfg.h b/scantool/diag_cfg.h index d02cc621..4180ae98 100644 --- a/scantool/diag_cfg.h +++ b/scantool/diag_cfg.h @@ -19,28 +19,30 @@ * Typically an L0 driver will alloc a linked-list of (struct cfgi) items */ struct cfgi { - const char *descr; //description; not mallocd - const char *shortname; //for CLI use, must be unique in any array of cfgi. Not mallocd. - int type; //indicate type of *val - #define CFGT_U8 1 //uint8_t, *val is a static buf - #define CFGT_INT 2 //int, *val is a static buf - #define CFGT_STR 3 //const char *; generic string; re-alloc/manage *val every time - //#define CFGT_TTY 4 //const char *; special string ? - //#define CFGT_ENUM 5 //redundant with ((type==CFGT_INT) && (numopts >0) )? - #define CFGT_BOOL 6 + const char *descr; // description; not mallocd + const char *shortname; // for CLI use, must be unique in any array of cfgi. Not + // mallocd. + int type; // indicate type of *val +#define CFGT_U8 1 // uint8_t, *val is a static buf +#define CFGT_INT 2 // int, *val is a static buf +#define CFGT_STR \ + 3 // const char *; generic string; re-alloc/manage *val every time + //#define CFGT_TTY 4 //const char *; special string ? +//#define CFGT_ENUM 5 //redundant with ((type==CFGT_INT) && (numopts >0) )? +#define CFGT_BOOL 6 union uval { - bool b; + bool b; uint8_t u8; - int i; + int i; char *str; - } val; //Actual value of parameter + } val; // Actual value of parameter union udval { - bool b; + bool b; uint8_t u8; - int i; + int i; char *str; - } dval; //default value; used for reset() + } dval; // default value; used for reset() /* these flags determine who owns & manages *val.str and *dval.str : * if set, diag_cfg_* functions take care of alloc / free calls. @@ -50,20 +52,23 @@ struct cfgi { bool dyn_val; bool dyn_dval; - int numopts; //if > 0 : number of predefined string options / enum values. If ==0 : value set directly. - char **opt; //description for each predefined option, i.e. numopts==1 means - // *opt[0]=="option_id 0 descr", etc. - // given { const char opt0_descr[]="option_id 0 descr"; const char *opt0_table[]={opt0_descr, opt1_descr}; } - // use { cfg_param->opt = opt0_table; } - bool dyn_opt; //if *opt[] must be free'd (recursively) + int numopts; // if > 0 : number of predefined string options / enum values. If ==0 + // : value set directly. + char **opt; // description for each predefined option, i.e. numopts==1 means + // *opt[0]=="option_id 0 descr", etc. + // given { const char opt0_descr[]="option_id 0 descr"; const char + // *opt0_table[]={opt0_descr, opt1_descr}; } use { cfg_param->opt = + // opt0_table; } + bool dyn_opt; // if *opt[] must be free'd (recursively) - - struct cfgi *next; //single-linked list + struct cfgi *next; // single-linked list /* do not call these directly */ - void (*refresh)(struct cfgi *_this); //called by diag_cfg_refresh() - // Possible problem with refresh() if numopts>0; and refresh() makes *val invalid / illegal ! - void (*reset)(struct cfgi *_this); //called by diag_cfg_reset() + void (*refresh)(struct cfgi *_this); // called by diag_cfg_refresh() + // Possible problem with refresh() if + // numopts>0; and refresh() makes *val + // invalid / illegal ! + void (*reset)(struct cfgi *_this); // called by diag_cfg_reset() }; /** Refresh opt[] and numopts (for tty, J2534, etc) @@ -78,7 +83,7 @@ void diag_cfg_refresh(struct cfgi *cfgp); */ void diag_cfg_reset(struct cfgi *cfgp); -//set config value for a param; caller must use the right func ... not super efficient +// set config value for a param; caller must use the right func ... not super efficient /** Set value for a CFGT_STR param * * @return 0 if ok @@ -90,8 +95,8 @@ int diag_cfg_setbool(struct cfgi *cfgp, bool val); int diag_cfg_setu8(struct cfgi *cfgp, uint8_t val); int diag_cfg_setint(struct cfgi *cfgp, int val); -//interpret 'str' correctly and set param accordingly -//int diag_cfg_set(struct cfgi *cfgp, const char *str); +// interpret 'str' correctly and set param accordingly +// int diag_cfg_set(struct cfgi *cfgp, const char *str); /** set config value to one of the predefined options. * @return 0 if ok. @@ -100,11 +105,11 @@ int diag_cfg_setint(struct cfgi *cfgp, int val); */ int diag_cfg_setopt(struct cfgi *cfgp, int optid); -//directly set param value (caller knows correct type and handles mem management, etc) BAD -//void diag_cfg_setraw(struct cfgi *cfgp, void *val); +// directly set param value (caller knows correct type and handles mem management, etc) BAD +// void diag_cfg_setraw(struct cfgi *cfgp, void *val); /** get param value: generates new string to be free'd by caller -*/ + */ char *diag_cfg_getstr(struct cfgi *cfgp); /** free contents of *cfgp but not the struct itself diff --git a/scantool/diag_dtc.c b/scantool/diag_dtc.c index d9686187..718fa577 100644 --- a/scantool/diag_dtc.c +++ b/scantool/diag_dtc.c @@ -29,11 +29,9 @@ #include "diag.h" #include "diag_dtc.h" - - -//do not use *allocs or open handles in diag_dtc_init ! -void diag_dtc_init(void) { -} +// do not use *allocs or open handles in diag_dtc_init ! +void +diag_dtc_init(void) {} /** DTC decoding routine. * @@ -48,10 +46,10 @@ void diag_dtc_init(void) { * @return pointer to *buf, which may be useful to printf or fprintf... */ -char *diag_dtc_decode(uint8_t *data, int len, - UNUSED(const char *vehicle), UNUSED(const char *ecu), - enum diag_dtc_protocol protocol, - char *buf, const size_t bufsize) { +char * +diag_dtc_decode(uint8_t *data, int len, UNUSED(const char *vehicle), + UNUSED(const char *ecu), enum diag_dtc_protocol protocol, char *buf, + const size_t bufsize) { char area; switch (protocol) { @@ -61,7 +59,7 @@ char *diag_dtc_decode(uint8_t *data, int len, return buf; } - switch ((data[0] >> 6) & 0x03) { /* Top 2 bits are area */ + switch ((data[0] >> 6) & 0x03) { /* Top 2 bits are area */ case 0: area = 'P'; break; @@ -79,7 +77,8 @@ char *diag_dtc_decode(uint8_t *data, int len, area = 'X'; break; } - snprintf(buf, bufsize, "%c%02X%02X ", area, data[0] & 0x3f, data[1]&0xff); + snprintf(buf, bufsize, "%c%02X%02X ", area, data[0] & 0x3f, + data[1] & 0xff); break; case dtc_proto_int8: diff --git a/scantool/diag_dtc.h b/scantool/diag_dtc.h index 66e39b8d..945364ee 100644 --- a/scantool/diag_dtc.h +++ b/scantool/diag_dtc.h @@ -33,21 +33,20 @@ extern "C" { #endif enum diag_dtc_protocol { - dtc_proto_j2012 = 1, /* SAE J2012 */ - dtc_proto_int8 = 2, /* 8 bit integer */ - dtc_proto_int16 = 3, /* 16 bit integer */ - dtc_proto_int32 = 4, /* 32 bit integer */ - dtc_proto_text = 5 /* Text String */ + dtc_proto_j2012 = 1, /* SAE J2012 */ + dtc_proto_int8 = 2, /* 8 bit integer */ + dtc_proto_int16 = 3, /* 16 bit integer */ + dtc_proto_int32 = 4, /* 32 bit integer */ + dtc_proto_text = 5 /* Text String */ }; -//do not use *allocs or open handles in diag_dtc_init ! +// do not use *allocs or open handles in diag_dtc_init ! void diag_dtc_init(void); -char *diag_dtc_decode(uint8_t *data, int len, - const char *vehicle, const char *ecu, enum diag_dtc_protocol protocol, - char *buf, const size_t bufsize); +char *diag_dtc_decode(uint8_t *data, int len, const char *vehicle, const char *ecu, + enum diag_dtc_protocol protocol, char *buf, const size_t bufsize); #if defined(__cplusplus) } -#endif +# endif #endif // _DIAG_DTC_H_ diff --git a/scantool/diag_err.h b/scantool/diag_err.h index 06a8983a..9ad0ba6b 100644 --- a/scantool/diag_err.h +++ b/scantool/diag_err.h @@ -30,35 +30,35 @@ extern "C" { #endif -//Note : update diag_general.c when modifying error codes -//Values should be <0, as many functions return a positive int on success -#define DIAG_ERR_GENERAL -1 /* Unspecified Error */ -#define DIAG_ERR_BADFD -2 /* Invalid FileDescriptor passed to routine */ -#define DIAG_ERR_NOMEM -3 /* Malloc/Calloc/Strdup/etc failed - ran out of memory */ +// Note : update diag_general.c when modifying error codes +// Values should be <0, as many functions return a positive int on success +#define DIAG_ERR_GENERAL -1 /* Unspecified Error */ +#define DIAG_ERR_BADFD -2 /* Invalid FileDescriptor passed to routine */ +#define DIAG_ERR_NOMEM -3 /* Malloc/Calloc/Strdup/etc failed - ran out of memory */ -#define DIAG_ERR_INIT_NOTSUPP -4 /* Initbus type not supported by H/W */ -#define DIAG_ERR_PROTO_NOTSUPP -5 /* Protocol not supported by H/W */ -#define DIAG_ERR_IOCTL_NOTSUPP -6 /* Ioctl type not supported */ -#define DIAG_ERR_BADIFADAPTER -7 /* L0 adapter comms failed */ +#define DIAG_ERR_INIT_NOTSUPP -4 /* Initbus type not supported by H/W */ +#define DIAG_ERR_PROTO_NOTSUPP -5 /* Protocol not supported by H/W */ +#define DIAG_ERR_IOCTL_NOTSUPP -6 /* Ioctl type not supported */ +#define DIAG_ERR_BADIFADAPTER -7 /* L0 adapter comms failed */ -#define DIAG_ERR_TIMEOUT -8 /* Read/Write timeout */ +#define DIAG_ERR_TIMEOUT -8 /* Read/Write timeout */ -#define DIAG_ERR_BUSERROR -16 /* We detected write error on diag bus */ -#define DIAG_ERR_BADLEN -17 /* Bad length for this i/f */ -#define DIAG_ERR_BADDATA -18 /* Cant decode msg (ever) */ -#define DIAG_ERR_BADCSUM -19 /* Bad checksum in recvd message */ -#define DIAG_ERR_INCDATA -20 /* Incomplete data, need to receive more */ -#define DIAG_ERR_WRONGKB -21 /* Wrong KeyBytes received */ -#define DIAG_ERR_BADRATE -22 /* Bit rate specified doesn't match ECU */ +#define DIAG_ERR_BUSERROR -16 /* We detected write error on diag bus */ +#define DIAG_ERR_BADLEN -17 /* Bad length for this i/f */ +#define DIAG_ERR_BADDATA -18 /* Cant decode msg (ever) */ +#define DIAG_ERR_BADCSUM -19 /* Bad checksum in recvd message */ +#define DIAG_ERR_INCDATA -20 /* Incomplete data, need to receive more */ +#define DIAG_ERR_WRONGKB -21 /* Wrong KeyBytes received */ +#define DIAG_ERR_BADRATE -22 /* Bit rate specified doesn't match ECU */ -#define DIAG_ERR_ECUSAIDNO -32 /* Ecu returned negative */ -#define DIAG_ERR_RCFILE -40 /* trouble with rc/ini file */ -#define DIAG_ERR_CMDFILE -41 /* trouble with sourcing commands */ +#define DIAG_ERR_ECUSAIDNO -32 /* Ecu returned negative */ +#define DIAG_ERR_RCFILE -40 /* trouble with rc/ini file */ +#define DIAG_ERR_CMDFILE -41 /* trouble with sourcing commands */ -#define DIAG_ERR_BADVAL -43 /* Invalid value passed to routine */ -#define DIAG_ERR_BADCFG -44 /* Bad config param */ +#define DIAG_ERR_BADVAL -43 /* Invalid value passed to routine */ +#define DIAG_ERR_BADCFG -44 /* Bad config param */ #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_ERR_H_ */ diff --git a/scantool/diag_general.c b/scantool/diag_general.c index f2eeb23e..35ee5655 100644 --- a/scantool/diag_general.c +++ b/scantool/diag_general.c @@ -37,30 +37,46 @@ #include "diag_dtc.h" #include "diag_l1.h" #include "diag_l2.h" +#include "diag_l3.h" #include "utlist.h" -#define ERR_STR_LEN 50 //length of "illegal error X" string +#define ERR_STR_LEN 50 // length of "illegal error X" string -static int diag_initialized=0; +DIAG_ATOMIC_STATICALLY_DECL_INIT(static diag_atomic_bool periodic_done_wrapper) -//diag_init : should be called once before doing anything. -//and call diag_end before terminating. -int diag_init(void) { //returns 0 if normal exit +static void +set_periodic_done(void) { + diag_atomic_store_bool(&periodic_done_wrapper, true); +} + +bool +periodic_done(void) { + return diag_atomic_load_bool(&periodic_done_wrapper); +} + +static int diag_initialized = 0; + +// diag_init : should be called once before doing anything. +// and call diag_end before terminating. +int diag_init(void) { // returns 0 if normal exit int rv; if (diag_initialized) { return 0; } - //XXX This is interesting: the following functions only ever return 0... + // XXX This is interesting: the following functions only ever return 0... + diag_l0_init(); if ((rv = diag_l1_init())) { return diag_iseterr(rv); } if ((rv = diag_l2_init())) { return diag_iseterr(rv); } + diag_l3_init(); + DIAG_ATOMIC_INITSTATIC(&periodic_done_wrapper); if ((rv = diag_os_init())) { return diag_iseterr(rv); } @@ -71,33 +87,41 @@ int diag_init(void) { //returns 0 if normal exit return 0; } -//must be called before exiting. Ret 0 if ok -//this is the "opposite" of diag_init -int diag_end(void) { - int rv=0; +// must be called before exiting. Ret 0 if ok +// this is the "opposite" of diag_init +int +diag_end(void) { + int rv = 0; if (!diag_initialized) { return 0; } + set_periodic_done(); + if (diag_os_close()) { + fprintf(stderr, FLFMT "Could not close OS functions!\n", FL); + rv = -1; + } + diag_l3_end(); if (diag_l2_end()) { fprintf(stderr, FLFMT "Could not close L2 level\n", FL); - rv=-1; + rv = -1; } if (diag_l1_end()) { fprintf(stderr, FLFMT "Could not close L1 level\n", FL); - rv=-1; - } - if (diag_os_close()) { - fprintf(stderr, FLFMT "Could not close OS functions!\n", FL); - rv=-1; + rv = -1; } - //nothing to do for diag_dtc_init + diag_l0_end(); - diag_initialized=0; + // There would be a race with the periodic timer, trying to take the lock, if we + // deleted the mutex. + // DIAG_ATOMIC_DEL(&periodic_done_wrapper) + + // nothing to do for diag_dtc_init + + diag_initialized = 0; return rv; } - /** Message handling **/ struct diag_msg * @@ -106,7 +130,8 @@ diag_allocmsg(size_t datalen) { int rv; if (datalen > DIAG_MAX_MSGLEN) { - fprintf(stderr, FLFMT "_allocmsg with >%d bytes !? report this !\n", FL, DIAG_MAX_MSGLEN); + fprintf(stderr, FLFMT "_allocmsg with >%d bytes !? report this !\n", FL, + DIAG_MAX_MSGLEN); return diag_pseterr(DIAG_ERR_BADLEN); } @@ -127,9 +152,9 @@ diag_allocmsg(size_t datalen) { newmsg->idata = NULL; } - newmsg->len=datalen; - newmsg->next=NULL; - newmsg->data = newmsg->idata; /* Keep tab as users change newmsg->data */ + newmsg->len = datalen; + newmsg->next = NULL; + newmsg->data = newmsg->idata; /* Keep tab as users change newmsg->data */ // i.e. some functions do (diagmsg->data += skiplen) which would prevent us // from doing free(diagmsg->data) (the pointer was changed). // so ->idata is the original alloc'ed pointer, that should never be modified @@ -138,7 +163,8 @@ diag_allocmsg(size_t datalen) { return newmsg; } -/* Duplicate a message, and its contents including all chained messages. XXX nobody uses this !? */ +/* Duplicate a message, and its contents including all chained messages. XXX nobody uses + * this !? */ struct diag_msg * diag_dupmsg(struct diag_msg *msg) { struct diag_msg *newchain, *chain_last, *tmsg; @@ -159,14 +185,15 @@ diag_dupmsg(struct diag_msg *msg) { chain_last = newchain; LL_FOREACH(msg->next, msg) { - tmsg = diag_dupsinglemsg(msg); //copy + tmsg = diag_dupsinglemsg(msg); // copy if (tmsg == NULL) { - diag_freemsg(newchain); //undo what we have so far + diag_freemsg(newchain); // undo what we have so far return diag_pseterr(DIAG_ERR_NOMEM); } - //append to end of chain. - //Not using LL_APPEND out of principle, to avoid walking the whole list every time ! + // append to end of chain. + // Not using LL_APPEND out of principle, to avoid walking the whole list + // every time ! chain_last->next = tmsg; chain_last = tmsg; } @@ -212,12 +239,14 @@ diag_freemsg(struct diag_msg *msg) { } if (msg->next != NULL) { - diag_freemsg(msg->next); //recurse + diag_freemsg(msg->next); // recurse } - if ( (msg->iflags & DIAG_MSG_IFLAG_MALLOC) == 0 ) { + if ((msg->iflags & DIAG_MSG_IFLAG_MALLOC) == 0) { fprintf(stderr, - FLFMT "diag_freemsg free-ing a non diag_allocmsg()'d message %p!\n", + FLFMT + "diag_freemsg free-ing a non diag_allocmsg()'d message " + "%p!\n", FL, (void *)msg); free(msg); return; @@ -231,11 +260,11 @@ diag_freemsg(struct diag_msg *msg) { return; } - // diag_cks1: return simple 8-bit checksum of // [len] bytes at *data. Everybody needs this ! -uint8_t diag_cks1(const uint8_t *data, unsigned int len) { - uint8_t rv=0; +uint8_t +diag_cks1(const uint8_t *data, unsigned int len) { + uint8_t rv = 0; while (len > 0) { len--; @@ -244,8 +273,8 @@ uint8_t diag_cks1(const uint8_t *data, unsigned int len) { return rv; } -//diag_data_dump : print (len) bytes of uint8_t *data -//to the specified FILE (stderr, etc.) +// diag_data_dump : print (len) bytes of uint8_t *data +// to the specified FILE (stderr, etc.) void diag_data_dump(FILE *out, const void *data, size_t len) { const uint8_t *p = (const uint8_t *)data; @@ -258,10 +287,11 @@ diag_data_dump(FILE *out, const void *data, size_t len) { } } -//smartcat() : make sure s1 is not too large, then strncat -//it does NOT verify if *p1 is large enough ! -void smartcat(char *p1, const size_t s1, const char *p2 ) { - assert ( s1 > strlen(p1) + strlen (p2) + 1 ) ; +// smartcat() : make sure s1 is not too large, then strncat +// it does NOT verify if *p1 is large enough ! +void +smartcat(char *p1, const size_t s1, const char *p2) { + assert(s1 > strlen(p1) + strlen(p2) + 1); strncat(p1, p2, s1); } @@ -276,30 +306,30 @@ static const struct { const int code; const char *desc; } edesc[] = { - { DIAG_ERR_GENERAL, "Unspecified Error" }, - { DIAG_ERR_BADFD, "Invalid FileDescriptor passed to routine" }, - { DIAG_ERR_NOMEM, "Malloc/Calloc/Strdup/etc failed - ran out of memory" }, - - { DIAG_ERR_INIT_NOTSUPP, "Initbus type not supported by H/W" }, - { DIAG_ERR_PROTO_NOTSUPP, "Protocol not supported by H/W" }, - { DIAG_ERR_IOCTL_NOTSUPP, "Ioctl type not supported" }, - { DIAG_ERR_BADIFADAPTER, "L0 adapter comms failed" }, - - { DIAG_ERR_TIMEOUT, "Read/Write timeout" }, - - { DIAG_ERR_BUSERROR, "We detected write error on diag bus" }, - { DIAG_ERR_BADLEN, "Bad length for this i/f" }, - { DIAG_ERR_BADDATA, "Cant decode msg (ever)" }, - { DIAG_ERR_BADCSUM, "Bad checksum in recvd message" }, - { DIAG_ERR_INCDATA, "Incomplete data, need to receive more" }, - { DIAG_ERR_WRONGKB, "Wrong KeyBytes received" }, - { DIAG_ERR_BADRATE, "Bit rate specified doesn't match ECU" }, - - { DIAG_ERR_ECUSAIDNO, "Ecu returned negative" }, - { DIAG_ERR_RCFILE, "Trouble loading .rc or .ini file" }, - { DIAG_ERR_CMDFILE, "Trouble with sourcing commands" }, - { DIAG_ERR_BADVAL, "Invalid value passed to routine" }, - { DIAG_ERR_BADCFG, "Bad config/param" }, + {DIAG_ERR_GENERAL, "Unspecified Error"}, + {DIAG_ERR_BADFD, "Invalid FileDescriptor passed to routine"}, + {DIAG_ERR_NOMEM, "Malloc/Calloc/Strdup/etc failed - ran out of memory"}, + + {DIAG_ERR_INIT_NOTSUPP, "Initbus type not supported by H/W"}, + {DIAG_ERR_PROTO_NOTSUPP, "Protocol not supported by H/W"}, + {DIAG_ERR_IOCTL_NOTSUPP, "Ioctl type not supported"}, + {DIAG_ERR_BADIFADAPTER, "L0 adapter comms failed"}, + + {DIAG_ERR_TIMEOUT, "Read/Write timeout"}, + + {DIAG_ERR_BUSERROR, "We detected write error on diag bus"}, + {DIAG_ERR_BADLEN, "Bad length for this i/f"}, + {DIAG_ERR_BADDATA, "Cant decode msg (ever)"}, + {DIAG_ERR_BADCSUM, "Bad checksum in recvd message"}, + {DIAG_ERR_INCDATA, "Incomplete data, need to receive more"}, + {DIAG_ERR_WRONGKB, "Wrong KeyBytes received"}, + {DIAG_ERR_BADRATE, "Bit rate specified doesn't match ECU"}, + + {DIAG_ERR_ECUSAIDNO, "Ecu returned negative"}, + {DIAG_ERR_RCFILE, "Trouble loading .rc or .ini file"}, + {DIAG_ERR_CMDFILE, "Trouble with sourcing commands"}, + {DIAG_ERR_BADVAL, "Invalid value passed to routine"}, + {DIAG_ERR_BADCFG, "Bad config/param"}, }; const char * @@ -312,11 +342,11 @@ diag_errlookup(const int code) { } } - snprintf(ill_str,ERR_STR_LEN,"Illegal error code: 0x%.2X\n",code); + snprintf(ill_str, ERR_STR_LEN, "Illegal error code: 0x%.2X\n", code); return ill_str; } -//do not call diag_pflseterr; refer to diag.h for related macros +// do not call diag_pflseterr; refer to diag.h for related macros void * diag_pflseterr(const char *name, const int line, const int code) { fprintf(stderr, "%s:%d: %s.\n", name, line, diag_errlookup(code)); @@ -352,8 +382,9 @@ diag_geterr(void) { // Stores pointer to a newly allocated buffer of n*s bytes to pp. // Also takes filename and line to report for debugging purposes. // Returns 0 in the absence of errors. -int diag_fl_alloc(const char *fName, const int line, - void **pp, size_t n, size_t s, bool allocIsCalloc) { +int +diag_fl_alloc(const char *fName, const int line, void **pp, size_t n, size_t s, + bool allocIsCalloc) { char allocator; char *errMsg = "%s:%d: %calloc(%ld, %ld) failed: %s\n"; @@ -368,8 +399,7 @@ int diag_fl_alloc(const char *fName, const int line, if (pp != NULL) { *pp = NULL; } - fprintf(stderr, errMsg, fName, line, allocator, - n, s, "Invalid arguments"); + fprintf(stderr, errMsg, fName, line, allocator, n, s, "Invalid arguments"); return diag_iseterr(DIAG_ERR_BADVAL); } @@ -379,27 +409,27 @@ int diag_fl_alloc(const char *fName, const int line, *pp = malloc(n * s); } if (*pp == NULL) { - fprintf(stderr, errMsg, fName, line, allocator, - n, s, strerror(errno)); + fprintf(stderr, errMsg, fName, line, allocator, n, s, strerror(errno)); return diag_iseterr(DIAG_ERR_NOMEM); } return 0; } /* Add a string to array-of-strings (argv style) -*/ -char **strlist_add(char **list, const char *news, int elems) { + */ +char ** +strlist_add(char **list, const char *news, int elems) { char **templist; char *temp; - assert( news != NULL ); + assert(news != NULL); temp = malloc((strlen(news) * sizeof(char)) + 1); if (temp == NULL) { return diag_pseterr(DIAG_ERR_NOMEM); } - templist = realloc(list, (elems + 1)* sizeof(char *)); + templist = realloc(list, (elems + 1) * sizeof(char *)); if (!templist) { free(temp); return diag_pseterr(DIAG_ERR_NOMEM); @@ -411,7 +441,8 @@ char **strlist_add(char **list, const char *news, int elems) { } /* Free argv-style list */ -void strlist_free(char **list, int elems) { +void +strlist_free(char **list, int elems) { if (!list) { return; } @@ -431,8 +462,7 @@ void strlist_free(char **list, int elems) { void diag_printmsg_header(FILE *fp, struct diag_msg *msg, bool timestamp, int msgnum) { if (timestamp) { - fprintf(fp, "%lu.%03lu: ", msg->rxtime / 1000, - msg->rxtime % 1000); + fprintf(fp, "%lu.%03lu: ", msg->rxtime / 1000, msg->rxtime % 1000); } fprintf(fp, "msg %02d src=0x%02X dest=0x%02X\n", msgnum, msg->src, msg->dest); fprintf(fp, "msg %02d data: ", msgnum); @@ -441,7 +471,7 @@ diag_printmsg_header(FILE *fp, struct diag_msg *msg, bool timestamp, int msgnum) void diag_printmsg(FILE *fp, struct diag_msg *msg, bool timestamp) { struct diag_msg *tmsg; - int i=0; + int i = 0; LL_FOREACH(msg, tmsg) { diag_printmsg_header(fp, tmsg, timestamp, i); @@ -454,3 +484,37 @@ diag_printmsg(FILE *fp, struct diag_msg *msg, bool timestamp) { i++; } } + +// Atomic access functions. + +void +diag_atomic_store_bool(diag_atomic_bool *a, bool d) { + diag_os_lock(&a->mtx); + a->v = d; + diag_os_unlock(&a->mtx); +} + +void +diag_atomic_store_int(diag_atomic_int *a, int d) { + diag_os_lock(&a->mtx); + a->v = d; + diag_os_unlock(&a->mtx); +} + +bool +diag_atomic_load_bool(diag_atomic_bool *a) { + bool r; + diag_os_lock(&a->mtx); + r = a->v; + diag_os_unlock(&a->mtx); + return r; +} + +int +diag_atomic_load_int(diag_atomic_int *a) { + int r; + diag_os_lock(&a->mtx); + r = a->v; + diag_os_unlock(&a->mtx); + return r; +} diff --git a/scantool/diag_iso14230.h b/scantool/diag_iso14230.h index 65b6d6d0..a146ca51 100644 --- a/scantool/diag_iso14230.h +++ b/scantool/diag_iso14230.h @@ -49,58 +49,56 @@ extern "C" { */ /* 00->0F SAE J1979 Diagnostic Test Modes */ -#define DIAG_KW2K_SI_STADS 0x10 /* startDiagnosticSession */ -#define DIAG_KW2K_SI_ER 0x11 /* ecuReset */ -#define DIAG_KW2K_SI_RDFFD 0x12 /* readFreezeFrameData */ -#define DIAG_KW2K_SI_RDTC 0x13 /* readDiagnosticTroubleCodes */ -#define DIAG_KW2K_SI_CDI 0x14 /* clearDiagnosticInformation */ - -#define DIAG_KW2K_SI_RDSODTC 0x17 /* readStatusOfDiagnosticTroubleCodes */ -#define DIAG_KW2K_SI_RDTCBS 0x18 /* readDiagnosticTroubleCodesByStatus */ - -#define DIAG_KW2K_SI_REID 0x1A /* readEcuId */ - -#define DIAG_KW2K_SI_STODS 0x20 /* stopDiagnosticSession */ -#define DIAG_KW2K_SI_RDDBLI 0x21 /* readDataByLocalId */ -#define DIAG_KW2K_SI_RDDBCI 0x22 /* readDataByCommonId */ -#define DIAG_KW2K_SI_RDMBA 0x23 /* readMemoryByAddress */ - -#define DIAG_KW2K_SI_SRDT 0x25 /* stopRepeatedDataTransmission - SSF only! */ -#define DIAG_KW2K_SI_SDR 0x26 /* setDataRates - SSF only!*/ -#define DIAG_KW2K_SI_SA 0x27 /* securityAccess */ - -#define DIAG_KW2K_SI_DDLI 0x2C /* dynamicallyDefineLocalId */ -#define DIAG_KW2K_SI_WRDBCI 0x2E /* writeDataByCommonId */ -#define DIAG_KW2K_SI_IOCBCI 0x2F /* inputOutputControlByCommonId */ -#define DIAG_KW2K_SI_IOCBLI 0x30 /* inputOutputControlByLocalId */ -#define DIAG_KW2K_SI_STARBLI 0x31 /* startRoutineByLocalID */ -#define DIAG_KW2K_SI_STORBLI 0x32 /* stopRoutineByLocalID */ -#define DIAG_KW2K_SI_RRRBLI 0x33 /* requestRoutineResultsByLocalId */ -#define DIAG_KW2K_SI_RD 0x34 /* requestDownload */ -#define DIAG_KW2K_SI_RU 0x35 /* requestUpload */ -#define DIAG_KW2K_SI_TD 0x36 /* transfer data */ -#define DIAG_KW2K_SI_RTE 0x37 /* request transfer exit */ -#define DIAG_KW2K_SI_STARBA 0x38 /* startRoutineByAddress */ -#define DIAG_KW2K_SI_STORBA 0x39 /* stopRoutineByAddress */ -#define DIAG_KW2K_SI_RRRBA 0x3A /* requestRoutineResultsByAddress */ -#define DIAG_KW2K_SI_WRDBLI 0x3B /* writeDataByLocalId */ - -#define DIAG_KW2K_SI_WRMBA 0x3D /* writeMemoryByAddress */ -#define DIAG_KW2K_SI_TP 0x3E /* testerPresent */ -#define DIAG_KW2K_SI_ESC 0x80 /* EscCode */ - -#define DIAG_KW2K_SI_SCR 0x81 /* startCommunication */ -#define DIAG_KW2K_SI_SPR 0x82 /* stopCommunication */ -#define DIAG_KW2K_SI_ATP 0x83 /* accessTimingParameters */ - +#define DIAG_KW2K_SI_STADS 0x10 /* startDiagnosticSession */ +#define DIAG_KW2K_SI_ER 0x11 /* ecuReset */ +#define DIAG_KW2K_SI_RDFFD 0x12 /* readFreezeFrameData */ +#define DIAG_KW2K_SI_RDTC 0x13 /* readDiagnosticTroubleCodes */ +#define DIAG_KW2K_SI_CDI 0x14 /* clearDiagnosticInformation */ + +#define DIAG_KW2K_SI_RDSODTC 0x17 /* readStatusOfDiagnosticTroubleCodes */ +#define DIAG_KW2K_SI_RDTCBS 0x18 /* readDiagnosticTroubleCodesByStatus */ + +#define DIAG_KW2K_SI_REID 0x1A /* readEcuId */ + +#define DIAG_KW2K_SI_STODS 0x20 /* stopDiagnosticSession */ +#define DIAG_KW2K_SI_RDDBLI 0x21 /* readDataByLocalId */ +#define DIAG_KW2K_SI_RDDBCI 0x22 /* readDataByCommonId */ +#define DIAG_KW2K_SI_RDMBA 0x23 /* readMemoryByAddress */ + +#define DIAG_KW2K_SI_SRDT 0x25 /* stopRepeatedDataTransmission - SSF only! */ +#define DIAG_KW2K_SI_SDR 0x26 /* setDataRates - SSF only!*/ +#define DIAG_KW2K_SI_SA 0x27 /* securityAccess */ + +#define DIAG_KW2K_SI_DDLI 0x2C /* dynamicallyDefineLocalId */ +#define DIAG_KW2K_SI_WRDBCI 0x2E /* writeDataByCommonId */ +#define DIAG_KW2K_SI_IOCBCI 0x2F /* inputOutputControlByCommonId */ +#define DIAG_KW2K_SI_IOCBLI 0x30 /* inputOutputControlByLocalId */ +#define DIAG_KW2K_SI_STARBLI 0x31 /* startRoutineByLocalID */ +#define DIAG_KW2K_SI_STORBLI 0x32 /* stopRoutineByLocalID */ +#define DIAG_KW2K_SI_RRRBLI 0x33 /* requestRoutineResultsByLocalId */ +#define DIAG_KW2K_SI_RD 0x34 /* requestDownload */ +#define DIAG_KW2K_SI_RU 0x35 /* requestUpload */ +#define DIAG_KW2K_SI_TD 0x36 /* transfer data */ +#define DIAG_KW2K_SI_RTE 0x37 /* request transfer exit */ +#define DIAG_KW2K_SI_STARBA 0x38 /* startRoutineByAddress */ +#define DIAG_KW2K_SI_STORBA 0x39 /* stopRoutineByAddress */ +#define DIAG_KW2K_SI_RRRBA 0x3A /* requestRoutineResultsByAddress */ +#define DIAG_KW2K_SI_WRDBLI 0x3B /* writeDataByLocalId */ + +#define DIAG_KW2K_SI_WRMBA 0x3D /* writeMemoryByAddress */ +#define DIAG_KW2K_SI_TP 0x3E /* testerPresent */ +#define DIAG_KW2K_SI_ESC 0x80 /* EscCode */ + +#define DIAG_KW2K_SI_SCR 0x81 /* startCommunication */ +#define DIAG_KW2K_SI_SPR 0x82 /* stopCommunication */ +#define DIAG_KW2K_SI_ATP 0x83 /* accessTimingParameters */ /* * Responses * * Positive responses are service ID + 0x40 */ -#define DIAG_KW2K_RC_NR 0x7F /* negative Response */ - +#define DIAG_KW2K_RC_NR 0x7F /* negative Response */ /* * Service response codes @@ -109,44 +107,45 @@ extern "C" { /* Negative Responses */ -#define DIAG_KW2K_RC_GR 0x10 /* generalReject */ -#define DIAG_KW2K_RC_SNS 0x11 /* serviceNotSupported */ -#define DIAG_KW2K_RC_SFNS_IF 0x12 /* subFunctionNotSupported-Invalid Format */ -#define DIAG_KW2K_RC_B_RR 0x21 /* busy-repeatRequest */ -#define DIAG_KW2K_RC_CNCORSE 0x22 /* conditionsNoteCorrectOrRequestSequenceError */ -#define DIAG_KW2K_RC_RNC 0x23 /* routineNotCompleteOrServiceInProgress */ -#define DIAG_KW2K_RC_ROOT 0x31 /* requestOutOfRange */ -#define DIAG_KW2K_RC_SAD_SAR 0x33 /* securityAccessDenied-securityAccessRequested */ -#define DIAG_KW2K_RC_IK 0x35 /* invalidKey */ -#define DIAG_KW2K_RC_ENOA 0x36 /* exceedNumberOfAttempts */ -#define DIAG_KW2K_RC_RTDNE 0x37 /* requiredTimeDelayNotExpired */ -#define DIAG_KW2K_RC_DNA 0x40 /* downloadNotAccepted */ -#define DIAG_KW2K_RC_IDT 0x41 /* improperDownloadType */ - -#define DIAG_KW2K_RC_CNDTSA 0x42 /* canNotDownloadToSpecifiedAddress */ -#define DIAG_KW2K_RC_CNDNOBR 0x43 /* canNotDownloadNumberOfBytesRequested */ -#define DIAG_KW2K_RC_UNA 0x50 /* uploadNotAccepted */ -#define DIAG_KW2K_RC_IUT 0x51 /* improperUploadType */ -#define DIAG_KW2K_RC_CNUFSA 0x52 /* canNotUploadFromSpecifiedAddress */ -#define DIAG_KW2K_RC_CNUNOBR 0x53 /* canNotUploadNumberOfBytesRequested */ -#define DIAG_KW2K_RC_TS 0x71 /* transferSuspended */ -#define DIAG_KW2K_RC_TA 0x72 /* transferAborted */ -#define DIAG_KW2K_RC_IAIBT 0x74 /* illegalAddressInBlockTransfer */ -#define DIAG_KW2K_RC_IBCIBT 0x75 /* illegalByteCountInBlockTransfer */ -#define DIAG_KW2K_RC_IBTT 0x76 /* illegalBlockTrasnferType */ -#define DIAG_KW2K_RC_BTCDE 0x77 /* blockTransferDataChecksumError */ -#define DIAG_KW2K_RC_RCR_RP 0x78 /* requestCorrectyRcvd-RspPending */ -#define DIAG_KW2K_RC_IBCDBT 0x79 /* incorrectByteCountDuringBlockTransfer */ -#define DIAG_KW2K_RC_SNSIADS 0x80 /* serviceNotSupportedInActiveDiagnosticMode - SSF only !*/ +#define DIAG_KW2K_RC_GR 0x10 /* generalReject */ +#define DIAG_KW2K_RC_SNS 0x11 /* serviceNotSupported */ +#define DIAG_KW2K_RC_SFNS_IF 0x12 /* subFunctionNotSupported-Invalid Format */ +#define DIAG_KW2K_RC_B_RR 0x21 /* busy-repeatRequest */ +#define DIAG_KW2K_RC_CNCORSE 0x22 /* conditionsNoteCorrectOrRequestSequenceError */ +#define DIAG_KW2K_RC_RNC 0x23 /* routineNotCompleteOrServiceInProgress */ +#define DIAG_KW2K_RC_ROOT 0x31 /* requestOutOfRange */ +#define DIAG_KW2K_RC_SAD_SAR 0x33 /* securityAccessDenied-securityAccessRequested */ +#define DIAG_KW2K_RC_IK 0x35 /* invalidKey */ +#define DIAG_KW2K_RC_ENOA 0x36 /* exceedNumberOfAttempts */ +#define DIAG_KW2K_RC_RTDNE 0x37 /* requiredTimeDelayNotExpired */ +#define DIAG_KW2K_RC_DNA 0x40 /* downloadNotAccepted */ +#define DIAG_KW2K_RC_IDT 0x41 /* improperDownloadType */ + +#define DIAG_KW2K_RC_CNDTSA 0x42 /* canNotDownloadToSpecifiedAddress */ +#define DIAG_KW2K_RC_CNDNOBR 0x43 /* canNotDownloadNumberOfBytesRequested */ +#define DIAG_KW2K_RC_UNA 0x50 /* uploadNotAccepted */ +#define DIAG_KW2K_RC_IUT 0x51 /* improperUploadType */ +#define DIAG_KW2K_RC_CNUFSA 0x52 /* canNotUploadFromSpecifiedAddress */ +#define DIAG_KW2K_RC_CNUNOBR 0x53 /* canNotUploadNumberOfBytesRequested */ +#define DIAG_KW2K_RC_TS 0x71 /* transferSuspended */ +#define DIAG_KW2K_RC_TA 0x72 /* transferAborted */ +#define DIAG_KW2K_RC_IAIBT 0x74 /* illegalAddressInBlockTransfer */ +#define DIAG_KW2K_RC_IBCIBT 0x75 /* illegalByteCountInBlockTransfer */ +#define DIAG_KW2K_RC_IBTT 0x76 /* illegalBlockTrasnferType */ +#define DIAG_KW2K_RC_BTCDE 0x77 /* blockTransferDataChecksumError */ +#define DIAG_KW2K_RC_RCR_RP 0x78 /* requestCorrectyRcvd-RspPending */ +#define DIAG_KW2K_RC_IBCDBT 0x79 /* incorrectByteCountDuringBlockTransfer */ +#define DIAG_KW2K_RC_SNSIADS \ + 0x80 /* serviceNotSupportedInActiveDiagnosticMode - SSF only !*/ // Note : responses >= 0x80 are MfgSpecifiCodes in ISO14230 ! /* Positive Responses */ /* 81-8F reserved */ /* 90-F9 vehicle manufacturer specific */ -#define DIAG_KW2K_RC_SCRPR 0xC1 /* StartComms +ve response */ -#define DIAG_KW2K_RC_SPRPR 0xC2 /* StopComms +ve response */ -#define DIAG_KW2K_RC_ATPPR 0xC3 /* AccessTimingParams +ve response */ +#define DIAG_KW2K_RC_SCRPR 0xC1 /* StartComms +ve response */ +#define DIAG_KW2K_RC_SPRPR 0xC2 /* StopComms +ve response */ +#define DIAG_KW2K_RC_ATPPR 0xC3 /* AccessTimingParams +ve response */ /* FA-FE system supplier specific */ /* FF reserved by document */ @@ -155,5 +154,5 @@ char *diag_l3_iso14230_decode_response(struct diag_msg *, char *, const size_t); #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_ISO14230_H_ */ diff --git a/scantool/diag_l0.c b/scantool/diag_l0.c index a97870f9..de53ec71 100644 --- a/scantool/diag_l0.c +++ b/scantool/diag_l0.c @@ -13,23 +13,45 @@ #include "diag_err.h" #include "diag_l0.h" -int diag_l0_debug; //debug flags for l0 +// debug flags for l0 +DIAG_ATOMIC_STATICALLY_DECL_INIT(static diag_atomic_int diag_l0_debug) +void +diag_l0_debug_store(int d) { + diag_atomic_store_int(&diag_l0_debug, d); +} +int +diag_l0_debug_load(void) { + return diag_atomic_load_int(&diag_l0_debug); +} + +void +diag_l0_init(void) { + DIAG_ATOMIC_INITSTATIC(&diag_l0_debug); +} -int diag_l0_open(struct diag_l0_device *dl0d, int l1proto) { +void +diag_l0_end(void) { + DIAG_ATOMIC_DEL(&diag_l0_debug); +} + +int +diag_l0_open(struct diag_l0_device *dl0d, int l1proto) { return dl0d->dl0->_open(dl0d, l1proto); } -void diag_l0_close(struct diag_l0_device *dl0d) { +void +diag_l0_close(struct diag_l0_device *dl0d) { dl0d->dl0->_close(dl0d); } -struct diag_l0_device *diag_l0_new(const char *shortname) { +struct diag_l0_device * +diag_l0_new(const char *shortname) { struct diag_l0_device *dl0d; int rv; const struct diag_l0 *l0dev; int i; - for (i=0; l0dev_list[i]; i++) { + for (i = 0; l0dev_list[i]; i++) { l0dev = l0dev_list[i]; if (strcmp(shortname, l0dev->shortname) == 0) { /* Found it */ @@ -38,11 +60,11 @@ struct diag_l0_device *diag_l0_new(const char *shortname) { } if (!l0dev_list[i]) { - //not found ! + // not found ! return NULL; } - rv=diag_calloc(&dl0d, 1); + rv = diag_calloc(&dl0d, 1); if (rv) { return diag_pseterr(rv); } @@ -57,8 +79,8 @@ struct diag_l0_device *diag_l0_new(const char *shortname) { return dl0d; } - -void diag_l0_del(struct diag_l0_device *dl0d) { +void +diag_l0_del(struct diag_l0_device *dl0d) { if (!dl0d) { return; } @@ -70,7 +92,8 @@ void diag_l0_del(struct diag_l0_device *dl0d) { return; } -struct cfgi *diag_l0_getcfg(struct diag_l0_device *dl0d) { +struct cfgi * +diag_l0_getcfg(struct diag_l0_device *dl0d) { if (!dl0d) { return NULL; } @@ -81,26 +104,29 @@ struct cfgi *diag_l0_getcfg(struct diag_l0_device *dl0d) { return NULL; } -uint32_t diag_l0_getflags(struct diag_l0_device *dl0d) { +uint32_t +diag_l0_getflags(struct diag_l0_device *dl0d) { assert(dl0d); return dl0d->dl0->_getflags(dl0d); } -int diag_l0_recv(struct diag_l0_device *dl0d, - const char *subinterface, void *data, size_t len, unsigned int timeout) { +int +diag_l0_recv(struct diag_l0_device *dl0d, const char *subinterface, void *data, size_t len, + unsigned int timeout) { assert(dl0d); return dl0d->dl0->_recv(dl0d, subinterface, data, len, timeout); } -int diag_l0_send(struct diag_l0_device *dl0d, - const char *subinterface, const void *data, size_t len) { +int +diag_l0_send(struct diag_l0_device *dl0d, const char *subinterface, const void *data, + size_t len) { assert(dl0d); return dl0d->dl0->_send(dl0d, subinterface, data, len); } -int diag_l0_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { +int +diag_l0_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { assert(dl0d); return dl0d->dl0->_ioctl(dl0d, cmd, data); } - diff --git a/scantool/diag_l0.h b/scantool/diag_l0.h index 715e2d98..8d3b1dac 100644 --- a/scantool/diag_l0.h +++ b/scantool/diag_l0.h @@ -11,7 +11,7 @@ extern "C" { #endif -#include "diag_cfg.h" //for cfgi +#include "diag_cfg.h" //for cfgi /* Cheats for structs defined elsewhere; * the alternate solution of including diag_l*.h gets messy fast @@ -27,34 +27,32 @@ struct diag_l0; * L0 device structure * This is the structure to interface between the L1 code * and the interface-manufacturer dependent code (in diag_l0_.c) - * A "diag_l0_device" is a unique association between an l0 driver (diag_l0_dumb for instance) - * and a hardware resource (serial port, file, etc.) + * A "diag_l0_device" is a unique association between an l0 driver (diag_l0_dumb for + * instance) and a hardware resource (serial port, file, etc.) */ struct diag_l0_device { - void *l0_int; /** Handle for internal L0 data */ - const struct diag_l0 *dl0; /** The L0 driver's diag_l0 */ + void *l0_int; /** Handle for internal L0 data */ + const struct diag_l0 *dl0; /** The L0 driver's diag_l0 */ - bool opened; /** L0 status */ + bool opened; /** L0 status */ }; - // diag_l0 : every diag_l0_???.c "driver" fills in one of these to describe itself. struct diag_l0 { - const char *longname; /* Useful textual name, unused at the moment */ - const char *shortname; /* Short, unique text name for user interface */ + const char *longname; /* Useful textual name, unused at the moment */ + const char *shortname; /* Short, unique text name for user interface */ - int l1proto_mask; /** supported L1protocols, defined in diag_l1.h */ + int l1proto_mask; /** supported L1protocols, defined in diag_l1.h */ /** set up global/default state of driver, if applicable * * @return 0 if ok * - * Note: the implementation must not do any dynamic mem operation (*alloc etc) or open handles. - * That way we won't need to add an _end function. + * Note: the implementation must not do any dynamic mem operation (*alloc etc) or + * open handles. That way we won't need to add an _end function. */ int (*init)(void); - /*** Private funcs, do not call directly ! ***/ /* These are called from the "public funcs" listed below. */ @@ -63,31 +61,33 @@ struct diag_l0 { void (*_del)(struct diag_l0_device *); int (*_open)(struct diag_l0_device *, int l1_proto); void (*_close)(struct diag_l0_device *); - uint32_t (*_getflags)(struct diag_l0_device *); + uint32_t (*_getflags)(struct diag_l0_device *); - int (*_recv)(struct diag_l0_device *, - const char *subinterface, void *data, size_t len, unsigned int timeout); - int (*_send)(struct diag_l0_device *, - const char *subinterface, const void *data, size_t len); + int (*_recv)(struct diag_l0_device *, const char *subinterface, void *data, + size_t len, unsigned int timeout); + int (*_send)(struct diag_l0_device *, const char *subinterface, const void *data, + size_t len); int (*_ioctl)(struct diag_l0_device *, unsigned cmd, void *data); }; +/***** Public funcs *****/ +// Call before anything else. +void diag_l0_init(void); -/***** Public funcs *****/ +// Call after everything is done. +void diag_l0_end(void); /** Alloc new dl0d and call L0's "_new"; * (no open, default params, etc) * @return 0 if ok */ struct diag_l0_device *diag_l0_new(const char *shortname); - /** Get linked-list of config items. * @return NULL if no items exist */ struct cfgi *diag_l0_getcfg(struct diag_l0_device *); - /** Delete L0 driver instance. * * Caller MUST have closed it first with diag_l0_close ! @@ -95,7 +95,6 @@ struct cfgi *diag_l0_getcfg(struct diag_l0_device *); */ void diag_l0_del(struct diag_l0_device *); - /** Open an L0 device with a given L1 proto * * @return 0 if ok @@ -104,34 +103,30 @@ void diag_l0_del(struct diag_l0_device *); */ int diag_l0_open(struct diag_l0_device *, int l1protocol); - /** Close diag_l0_device * * Does not free the struct itself, to allow reuse. */ void diag_l0_close(struct diag_l0_device *); - /** Get L0 device flags * @return bitmask of flags defined in diag_l1.h */ -uint32_t diag_l0_getflags(struct diag_l0_device *); - +uint32_t diag_l0_getflags(struct diag_l0_device *); /** Receive bytes. * @param timeout: in ms * @return # of bytes read */ -int diag_l0_recv(struct diag_l0_device *, - const char *subinterface, void *data, size_t len, unsigned int timeout); - +int diag_l0_recv(struct diag_l0_device *, const char *subinterface, void *data, size_t len, + unsigned int timeout); /** Send bytes. * @param subinterface: ignored * @return 0 on success */ -int diag_l0_send(struct diag_l0_device *, - const char *subinterface, const void *data, size_t len); +int diag_l0_send(struct diag_l0_device *, const char *subinterface, const void *data, + size_t len); /** Send IOCTL to L0 * @param command : IOCTL #, defined in diag.h @@ -140,20 +135,20 @@ int diag_l0_send(struct diag_l0_device *, */ int diag_l0_ioctl(struct diag_l0_device *, unsigned cmd, void *data); - /*** globals ***/ -extern int diag_l0_debug; // debug flags - +// debug flags +void diag_l0_debug_store(int d); +int diag_l0_debug_load(void); /* * l0dev_list : static-allocated list of supported L0 devices, since it can * be entirely determined at compile-time. * The last item is a NULL ptr to ease iterating. */ -extern const struct diag_l0 *l0dev_list[]; /* defined in diag_config.c */ +extern const struct diag_l0 *l0dev_list[]; /* defined in diag_config.c */ #if defined(__cplusplus) } -#endif +# endif #endif // _DIAG_L0_H_ diff --git a/scantool/diag_l0_br.c b/scantool/diag_l0_br.c index 6e6da221..ec953bd5 100644 --- a/scantool/diag_l0_br.c +++ b/scantool/diag_l0_br.c @@ -26,7 +26,7 @@ * support ISO14230 (KWP2000). In ISO9141-2 mode, only supports the * ISO9141-2 address (0x33h) * - * + * * Thank you to B. Roadman for donation of an interface to the prject * */ @@ -42,59 +42,58 @@ #include "diag_l0.h" #include "diag_l1.h" - extern const struct diag_l0 diag_l0_br; /* * States */ -enum BR_STATE {BR_STATE_CLOSED, BR_STATE_KWP_SENDKB1, - BR_STATE_KWP_SENDKB2, BR_STATE_KWP_FASTINIT, - BR_STATE_OPEN }; +enum BR_STATE { + BR_STATE_CLOSED, + BR_STATE_KWP_SENDKB1, + BR_STATE_KWP_SENDKB2, + BR_STATE_KWP_FASTINIT, + BR_STATE_OPEN +}; struct br_device { int protocol; - int dev_features; /* Device features */ - enum BR_STATE dev_state; /* State for 5 baud startup stuff */ - uint8_t dev_kb1; /* KB1/KB2 for 5 baud startup stuff */ + int dev_features; /* Device features */ + enum BR_STATE dev_state; /* State for 5 baud startup stuff */ + uint8_t dev_kb1; /* KB1/KB2 for 5 baud startup stuff */ uint8_t dev_kb2; + uint8_t dev_rxbuf[MAXRBUF]; /* Receive buffer XXX need to be this big? */ + int dev_rxlen; /* Length of data in buffer */ + int dev_rdoffset; /* Offset to read from to */ - uint8_t dev_rxbuf[MAXRBUF]; /* Receive buffer XXX need to be this big? */ - int dev_rxlen; /* Length of data in buffer */ - int dev_rdoffset; /* Offset to read from to */ + uint8_t dev_txbuf[16]; /* Copy of last sent frame */ + unsigned int dev_txlen; /* And length */ - uint8_t dev_txbuf[16]; /* Copy of last sent frame */ - unsigned int dev_txlen; /* And length */ + uint8_t dev_framenr; /* Frame nr for vpw/pwm */ - uint8_t dev_framenr; /* Frame nr for vpw/pwm */ - - struct cfgi port; - ttyp *tty_int; /** handle for tty stuff */ + struct cfgi port; + ttyp *tty_int; /** handle for tty stuff */ }; /* * Device features (depends on s/w version on the BR-1 device) */ -#define BR_FEATURE_2BYTE 0x01 /* 2 byte initialisation responses */ -#define BR_FEATURE_SETADDR 0x02 /* User can specifiy ISO address */ -#define BR_FEATURE_FASTINIT 0x04 /* ISO14230 fast init supported */ - +#define BR_FEATURE_2BYTE 0x01 /* 2 byte initialisation responses */ +#define BR_FEATURE_SETADDR 0x02 /* User can specifiy ISO address */ +#define BR_FEATURE_FASTINIT 0x04 /* ISO14230 fast init supported */ -static int br_getmsg(struct diag_l0_device *dl0d, - uint8_t *dp, unsigned int timeout); +static int br_getmsg(struct diag_l0_device *dl0d, uint8_t *dp, unsigned int timeout); -static int br_initialise(struct diag_l0_device *dl0d, - uint8_t type, uint8_t addr); +static int br_initialise(struct diag_l0_device *dl0d, uint8_t type, uint8_t addr); -static int br_writemsg(struct diag_l0_device *dl0d, - uint8_t type, const void *dp, size_t txlen); +static int +br_writemsg(struct diag_l0_device *dl0d, uint8_t type, const void *dp, size_t txlen); static void br_close(struct diag_l0_device *dl0d); /* Types for writemsg - corresponds to top bit values for the control byte */ -#define BR_WRTYPE_DATA 0x00 -#define BR_WRTYPE_INIT 0x40 +#define BR_WRTYPE_DATA 0x00 +#define BR_WRTYPE_INIT 0x40 /* * Init must be callable even if no physical interface is @@ -104,7 +103,7 @@ static void br_close(struct diag_l0_device *dl0d); static int br_init(void) { /* Global init flag */ - static int br_initdone=0; + static int br_initdone = 0; if (br_initdone) { return 0; @@ -142,7 +141,8 @@ br_new(struct diag_l0_device *dl0d) { return 0; } -static void br_del(struct diag_l0_device *dl0d) { +static void +br_del(struct diag_l0_device *dl0d) { struct br_device *dev; assert(dl0d); @@ -157,7 +157,8 @@ static void br_del(struct diag_l0_device *dl0d) { return; } -static struct cfgi *br_getcfg(struct diag_l0_device *dl0d) { +static struct cfgi * +br_getcfg(struct diag_l0_device *dl0d) { struct br_device *dev; if (dl0d == NULL) { return diag_pseterr(DIAG_ERR_BADCFG); @@ -175,7 +176,7 @@ br_close(struct diag_l0_device *dl0d) { struct br_device *dev = dl0d->l0_int; - if (diag_l0_debug & DIAG_DEBUG_CLOSE) { + if (diag_l0_debug_load() & DIAG_DEBUG_CLOSE) { fprintf(stderr, FLFMT "link %p closing\n", FL, (void *)dl0d); } @@ -194,7 +195,7 @@ br_write(struct diag_l0_device *dl0d, const void *dp, size_t txlen) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_tty_write(dev->tty_int, dp, txlen) != (int) txlen) { + if (diag_tty_write(dev->tty_int, dp, txlen) != (int)txlen) { fprintf(stderr, FLFMT "br_write error\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } @@ -206,10 +207,11 @@ br_write(struct diag_l0_device *dl0d, const void *dp, size_t txlen) { * Open the diagnostic device, return a file descriptor, * record the original state of term interface so we can restore later */ -static int br_open(struct diag_l0_device *dl0d, int iProtocol) { +static int +br_open(struct diag_l0_device *dl0d, int iProtocol) { struct br_device *dev = dl0d->l0_int; int rv; - uint8_t buf[4]; /* Was MAXRBUF. We only use 1! */ + uint8_t buf[4]; /* Was MAXRBUF. We only use 1! */ struct diag_serial_settings set; br_init(); @@ -227,7 +229,7 @@ static int br_open(struct diag_l0_device *dl0d, int iProtocol) { return diag_iseterr(DIAG_ERR_GENERAL); } - if (diag_l0_debug & DIAG_DEBUG_OPEN) { + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "features 0x%X\n", FL, dev->dev_features); } @@ -243,7 +245,7 @@ static int br_open(struct diag_l0_device *dl0d, int iProtocol) { return diag_iseterr(DIAG_ERR_GENERAL); } - diag_tty_iflush(dev->tty_int); /* Flush unread input data */ + diag_tty_iflush(dev->tty_int); /* Flush unread input data */ /* * Initialise the BR1 interface by sending the CHIP CONNECT @@ -251,25 +253,25 @@ static int br_open(struct diag_l0_device *dl0d, int iProtocol) { */ buf[0] = 0x20; if (br_write(dl0d, buf, 1)) { - if ((diag_l0_debug&DIAG_DEBUG_OPEN)) { - fprintf(stderr, FLFMT "CHIP CONNECT write failed link %p\n", - FL, (void *)dl0d); + if ((diag_l0_debug_load() & DIAG_DEBUG_OPEN)) { + fprintf(stderr, FLFMT "CHIP CONNECT write failed link %p\n", FL, + (void *)dl0d); } br_close(dl0d); return diag_iseterr(DIAG_ERR_BADIFADAPTER); } /* And expect 0xff as a response */ if (diag_tty_read(dev->tty_int, buf, 1, 100) != 1) { - if (diag_l0_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "CHIP CONNECT read failed link %p\n", - FL, (void *)dl0d); + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "CHIP CONNECT read failed link %p\n", FL, + (void *)dl0d); } br_close(dl0d); return diag_iseterr(DIAG_ERR_BADIFADAPTER); } if (buf[0] != 0xff) { - if (diag_l0_debug & DIAG_DEBUG_OPEN) { + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "CHIP CONNECT rcvd 0x%X != 0xff, link %p\n", FL, buf[0], (void *)dl0d); } @@ -297,31 +299,28 @@ static int br_open(struct diag_l0_device *dl0d, int iProtocol) { return diag_iseterr(rv); } - if (diag_l0_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "open succeeded link %p features 0x%X\n", - FL, (void *)dl0d, dev->dev_features); + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "open succeeded link %p features 0x%X\n", FL, + (void *)dl0d, dev->dev_features); } dl0d->opened = 1; return 0; } - /* * Do BR interface protocol initialisation, * returns -1 on error or the keybyte value */ static int br_initialise(struct diag_l0_device *dl0d, uint8_t type, uint8_t addr) { - struct br_device *dev = - (struct br_device *)dl0d->l0_int; + struct br_device *dev = (struct br_device *)dl0d->l0_int; uint8_t txbuf[3]; uint8_t rxbuf[MAXRBUF]; int rv; unsigned int timeout; - /* * Send initialisation message, 42H 0YH * - where Y is iniitialisation type @@ -332,7 +331,7 @@ br_initialise(struct diag_l0_device *dl0d, uint8_t type, uint8_t addr) { txbuf[2] = addr; if (type == 0x02) { - timeout = 6000; /* 5 baud init is slow */ + timeout = 6000; /* 5 baud init is slow */ if (dev->dev_features & BR_FEATURE_SETADDR) { txbuf[0] = 0x42; rv = br_write(dl0d, txbuf, 3); @@ -389,14 +388,13 @@ br_initialise(struct diag_l0_device *dl0d, uint8_t type, uint8_t addr) { * keybytes */ static int -br_slowinit( struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { - struct br_device *dev = - (struct br_device *)dl0d->l0_int; +br_slowinit(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { + struct br_device *dev = (struct br_device *)dl0d->l0_int; /* * Slow init * Build message into send buffer, and calculate checksum */ - uint8_t buf[16]; //limited by br_writemsg + uint8_t buf[16]; // limited by br_writemsg int rv; buf[0] = 0x02; @@ -420,7 +418,7 @@ br_slowinit( struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { /* * Now set the keybytes from what weve sent */ - if (rv == 1) { /* 1 byte response, old type interface */ + if (rv == 1) { /* 1 byte response, old type interface */ dev->dev_kb1 = buf[0]; dev->dev_kb2 = buf[0]; } else { @@ -449,12 +447,9 @@ br_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { dev = (struct br_device *)dl0d->l0_int; - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { - fprintf(stderr, - FLFMT - "device link %p info %p initbus type %d proto %d\n", - FL, (void *)dl0d, (void *)dev, in->type, - dev ? dev->protocol : -1); + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { + fprintf(stderr, FLFMT "device link %p info %p initbus type %d proto %d\n", + FL, (void *)dl0d, (void *)dev, in->type, dev ? dev->protocol : -1); } if (!dev) { @@ -481,7 +476,7 @@ br_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { rv = DIAG_ERR_INIT_NOTSUPP; break; } - return rv? diag_iseterr(rv):0 ; + return rv ? diag_iseterr(rv) : 0; } /* @@ -499,10 +494,10 @@ br_getmsg(struct diag_l0_device *dl0d, uint8_t *dp, unsigned int timeout) { int rv; struct br_device *dev = dl0d->l0_int; - if ( (diag_l0_debug & (DIAG_DEBUG_READ|DIAG_DEBUG_DATA)) == - (DIAG_DEBUG_READ|DIAG_DEBUG_DATA) ) { - fprintf(stderr, FLFMT "link %p getmsg timeout %u\n", - FL, (void *)dl0d, timeout); + if ((diag_l0_debug_load() & (DIAG_DEBUG_READ | DIAG_DEBUG_DATA)) == + (DIAG_DEBUG_READ | DIAG_DEBUG_DATA)) { + fprintf(stderr, FLFMT "link %p getmsg timeout %u\n", FL, (void *)dl0d, + timeout); } /* @@ -510,10 +505,10 @@ br_getmsg(struct diag_l0_device *dl0d, uint8_t *dp, unsigned int timeout) { */ rv = diag_tty_read(dev->tty_int, &firstbyte, 1, timeout); if (rv != 1) { - if ( (diag_l0_debug & (DIAG_DEBUG_READ|DIAG_DEBUG_DATA)) == - (DIAG_DEBUG_READ|DIAG_DEBUG_DATA) ) { - fprintf(stderr, FLFMT "link %p getmsg 1st byte timed out\n", - FL, (void *)dl0d); + if ((diag_l0_debug_load() & (DIAG_DEBUG_READ | DIAG_DEBUG_DATA)) == + (DIAG_DEBUG_READ | DIAG_DEBUG_DATA)) { + fprintf(stderr, FLFMT "link %p getmsg 1st byte timed out\n", FL, + (void *)dl0d); } return diag_iseterr(rv); } @@ -534,10 +529,10 @@ br_getmsg(struct diag_l0_device *dl0d, uint8_t *dp, unsigned int timeout) { return diag_iseterr(DIAG_ERR_GENERAL); } - if ( (diag_l0_debug & (DIAG_DEBUG_READ|DIAG_DEBUG_DATA)) == - (DIAG_DEBUG_READ|DIAG_DEBUG_DATA) ) { - fprintf(stderr, FLFMT "link %p getmsg read ctl 0x%X data:", - FL, (void *)dl0d, firstbyte & 0xff); + if ((diag_l0_debug_load() & (DIAG_DEBUG_READ | DIAG_DEBUG_DATA)) == + (DIAG_DEBUG_READ | DIAG_DEBUG_DATA)) { + fprintf(stderr, FLFMT "link %p getmsg read ctl 0x%X data:", FL, + (void *)dl0d, firstbyte & 0xff); diag_data_dump(stderr, dp, readlen); printf("\n"); } @@ -559,10 +554,9 @@ br_getmsg(struct diag_l0_device *dl0d, uint8_t *dp, unsigned int timeout) { return diag_iseterr(DIAG_ERR_TIMEOUT); } - return (int) readlen; + return (int)readlen; } - /* * Write Message routine. Adds the length byte to the data before sending, * and the frame number for VPW/PWM. The type is used to set the top bits @@ -572,33 +566,30 @@ br_getmsg(struct diag_l0_device *dl0d, uint8_t *dp, unsigned int timeout) { * txlen must be <= 15 */ static int -br_writemsg(struct diag_l0_device *dl0d, uint8_t type, - const void *dp, size_t txlen) { - struct br_device *dev = - (struct br_device *)dl0d->l0_int; +br_writemsg(struct diag_l0_device *dl0d, uint8_t type, const void *dp, size_t txlen) { + struct br_device *dev = (struct br_device *)dl0d->l0_int; int rv, j1850mode; uint8_t outb; - if ( (diag_l0_debug & (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA)) == - (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA) ) { - fprintf(stderr, FLFMT "device %p link %p sending to BR1\n", - FL, (void *)dev, (void *)dl0d); + if ((diag_l0_debug_load() & (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) == + (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) { + fprintf(stderr, FLFMT "device %p link %p sending to BR1\n", FL, + (void *)dev, (void *)dl0d); } if (txlen > 15) { return diag_iseterr(DIAG_ERR_BADLEN); } - if ((dev->protocol == DIAG_L1_J1850_VPW) || - (dev->protocol == DIAG_L1_J1850_PWM)) { + if ((dev->protocol == DIAG_L1_J1850_VPW) || (dev->protocol == DIAG_L1_J1850_PWM)) { j1850mode = 1; - outb = (uint8_t) txlen + 1; /* We also send a frame number */ + outb = (uint8_t)txlen + 1; /* We also send a frame number */ } else { j1850mode = 0; - outb = (uint8_t) txlen; + outb = (uint8_t)txlen; } - outb |= type; /* Set the type bits on the control byte */ + outb |= type; /* Set the type bits on the control byte */ /* Send the length byte */ rv = br_write(dl0d, &outb, 1); @@ -607,11 +598,10 @@ br_writemsg(struct diag_l0_device *dl0d, uint8_t type, } /* And now the data */ - if ( (diag_l0_debug & (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA)) == - (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA) ) { - fprintf(stderr, FLFMT "device %p writing data: ", - FL, (void *)dev); - fprintf(stderr,"0x%X ", (int)outb); /* Length byte */ + if ((diag_l0_debug_load() & (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) == + (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) { + fprintf(stderr, FLFMT "device %p writing data: ", FL, (void *)dev); + fprintf(stderr, "0x%X ", (int)outb); /* Length byte */ diag_data_dump(stderr, dp, txlen); fprintf(stderr, "\n"); } @@ -626,11 +616,10 @@ br_writemsg(struct diag_l0_device *dl0d, uint8_t type, * in order to receive multiple frames. */ if (j1850mode) { - if ( (diag_l0_debug & (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA)) == - (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA) ) { - fprintf(stderr, - FLFMT "device %p writing data: 0x%X\n", - FL, (void *)dev, dev->dev_framenr & 0xff); + if ((diag_l0_debug_load() & (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) == + (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) { + fprintf(stderr, FLFMT "device %p writing data: 0x%X\n", FL, + (void *)dev, dev->dev_framenr & 0xff); } rv = br_write(dl0d, &dev->dev_framenr, 1); if (rv < 0) { @@ -640,7 +629,6 @@ br_writemsg(struct diag_l0_device *dl0d, uint8_t type, return 0; } - /* * Send a load of data * @@ -650,9 +638,8 @@ br_writemsg(struct diag_l0_device *dl0d, uint8_t type, * will have been done by the slowinit() code */ static int -br_send(struct diag_l0_device *dl0d, -UNUSED(const char *subinterface), -const void *data, size_t len) { +br_send(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), const void *data, + size_t len) { int rv = 0; struct br_device *dev; @@ -663,16 +650,15 @@ const void *data, size_t len) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l0_debug & DIAG_DEBUG_WRITE) { + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { fprintf(stderr, - FLFMT "device link %p send %ld bytes protocol %d state %d: ", - FL, (void *)dl0d, (long)len, - dev->protocol, dev->dev_state); - if (diag_l0_debug & DIAG_DEBUG_DATA) { + FLFMT "device link %p send %ld bytes protocol %d state %d: ", FL, + (void *)dl0d, (long)len, dev->protocol, dev->dev_state); + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { diag_data_dump(stderr, data, len); fprintf(stderr, "\n"); } else { - fprintf(stderr,"\n"); + fprintf(stderr, "\n"); } } @@ -697,8 +683,7 @@ const void *data, size_t len) { */ outbuf[0] = 0x03; memcpy(&outbuf[1], dev->dev_txbuf, 5); - rv = br_writemsg(dl0d, BR_WRTYPE_INIT, - outbuf, 6); + rv = br_writemsg(dl0d, BR_WRTYPE_INIT, outbuf, 6); /* Stays in FASTINIT state until first read */ } } else { @@ -730,9 +715,8 @@ const void *data, size_t len) { * If control byte is < 16, it's a length byte, else it's a error descriptor */ static int -br_recv(struct diag_l0_device *dl0d, -UNUSED(const char *subinterface), -void *data, size_t len, unsigned int timeout) { +br_recv(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), void *data, + size_t len, unsigned int timeout) { int xferd, rv, retrycnt; uint8_t *pdata = (uint8_t *)data; @@ -743,7 +727,7 @@ void *data, size_t len, unsigned int timeout) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l0_debug & DIAG_DEBUG_READ) { + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "link %p recv upto %ld bytes timeout %u, rxlen %d " @@ -754,38 +738,42 @@ void *data, size_t len, unsigned int timeout) { } switch (dev->dev_state) { - case BR_STATE_KWP_FASTINIT: - /* Extend timeouts */ - timeout = 300; + case BR_STATE_KWP_FASTINIT: + /* Extend timeouts */ + timeout = 300; + dev->dev_state = BR_STATE_OPEN; + break; + case BR_STATE_KWP_SENDKB1: + if (len >= 2) { + pdata[0] = dev->dev_kb1; + pdata[1] = dev->dev_kb2; dev->dev_state = BR_STATE_OPEN; - break; - case BR_STATE_KWP_SENDKB1: - if (len >= 2) { - pdata[0] = dev->dev_kb1; - pdata[1] = dev->dev_kb2; - dev->dev_state = BR_STATE_OPEN; - return 2; - } else if (len == 1) { - *pdata = dev->dev_kb1; - dev->dev_state = BR_STATE_KWP_SENDKB2; - return 1; - } - return 0; /* Strange, user asked for 0 bytes */ - break; - case BR_STATE_KWP_SENDKB2: - if (len >= 1) { - *pdata = dev->dev_kb2; - dev->dev_state = BR_STATE_OPEN; - return 1; - } - return 0; /* Strange, user asked for 0 bytes */ - break; - default: - //So BR_STATE_CLOSED and BR_STATE_OPEN. - // I don't know what's supposed to happen here, so - fprintf(stderr, FLFMT "Warning : landed in a strange place. Report this please !\n", FL); - return 0; - break; + return 2; + } else if (len == 1) { + *pdata = dev->dev_kb1; + dev->dev_state = BR_STATE_KWP_SENDKB2; + return 1; + } + return 0; /* Strange, user asked for 0 bytes */ + break; + case BR_STATE_KWP_SENDKB2: + if (len >= 1) { + *pdata = dev->dev_kb2; + dev->dev_state = BR_STATE_OPEN; + return 1; + } + return 0; /* Strange, user asked for 0 bytes */ + break; + default: + // So BR_STATE_CLOSED and BR_STATE_OPEN. + // I don't know what's supposed to happen here, so + fprintf(stderr, + FLFMT + "Warning : landed in a strange place. Report this please " + "!\n", + FL); + return 0; + break; } switch (dev->protocol) { @@ -817,9 +805,8 @@ void *data, size_t len, unsigned int timeout) { * frame number to see if any more data is ready */ if (dev->dev_framenr > 1) { - rv = br_writemsg(dl0d, - BR_WRTYPE_DATA, - dev->dev_txbuf, (size_t)dev->dev_txlen); + rv = br_writemsg(dl0d, BR_WRTYPE_DATA, dev->dev_txbuf, + (size_t)dev->dev_txlen); } dev->dev_framenr++; @@ -831,15 +818,13 @@ void *data, size_t len, unsigned int timeout) { dev->dev_rxlen = rv; break; } - if ((rv != DIAG_ERR_BUSERROR) || - (retrycnt >= 30)) { + if ((rv != DIAG_ERR_BUSERROR) || (retrycnt >= 30)) { dev->dev_rxlen = 0; return rv; } /* Need to resend and try again */ - rv = br_writemsg(dl0d, - BR_WRTYPE_DATA, dev->dev_txbuf, - (size_t)dev->dev_txlen); + rv = br_writemsg(dl0d, BR_WRTYPE_DATA, dev->dev_txbuf, + (size_t)dev->dev_txlen); if (rv < 0) { return rv; } @@ -852,20 +837,19 @@ void *data, size_t len, unsigned int timeout) { if (bufbytes <= len) { memcpy(data, &dev->dev_rxbuf[dev->dev_rdoffset], bufbytes); dev->dev_rxlen = dev->dev_rdoffset = 0; - return (int) bufbytes; + return (int)bufbytes; } memcpy(data, &dev->dev_rxbuf[dev->dev_rdoffset], len); dev->dev_rdoffset += len; - return (int) len; + return (int)len; } xferd = 0; break; } /* OK, got whole message */ - if (diag_l0_debug & DIAG_DEBUG_READ) { - fprintf(stderr, - FLFMT "link %p received from BR1: ", FL, (void *)dl0d); + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "link %p received from BR1: ", FL, (void *)dl0d); diag_data_dump(stderr, data, (size_t)xferd); fprintf(stderr, "\n"); } @@ -873,7 +857,6 @@ void *data, size_t len, unsigned int timeout) { return xferd; } - static uint32_t br_getflags(struct diag_l0_device *dl0d) { /* @@ -889,33 +872,33 @@ br_getflags(struct diag_l0_device *dl0d) { switch (dev->protocol) { case DIAG_L1_J1850_VPW: case DIAG_L1_J1850_PWM: - flags = DIAG_L1_DOESL2FRAME; - break; + flags = DIAG_L1_DOESL2FRAME; + break; case DIAG_L1_ISO9141: - flags = DIAG_L1_SLOW; - flags |= DIAG_L1_DOESP4WAIT; - break; + flags = DIAG_L1_SLOW; + flags |= DIAG_L1_DOESP4WAIT; + break; case DIAG_L1_ISO14230: - flags = DIAG_L1_SLOW | DIAG_L1_FAST | DIAG_L1_PREFFAST; - flags |= DIAG_L1_DOESP4WAIT; - break; + flags = DIAG_L1_SLOW | DIAG_L1_FAST | DIAG_L1_PREFFAST; + flags |= DIAG_L1_DOESP4WAIT; + break; } - if (diag_l0_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "getflags link %p proto %d flags 0x%X\n", - FL, (void *)dl0d, dev->protocol, flags); + if (diag_l0_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "getflags link %p proto %d flags 0x%X\n", FL, + (void *)dl0d, dev->protocol, flags); } return flags; } - -static int br_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { +static int +br_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { int rv = 0; switch (cmd) { case DIAG_IOCTL_IFLUSH: - //do nothing + // do nothing rv = 0; break; case DIAG_IOCTL_INITBUS: @@ -929,20 +912,17 @@ static int br_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { return rv; } -const struct diag_l0 diag_l0_br = { - "B. Roadman BR-1 interface", - "BR1", - DIAG_L1_J1850_VPW | DIAG_L1_J1850_PWM | - DIAG_L1_ISO9141 | DIAG_L1_ISO14230, - br_init, - br_new, - br_getcfg, - br_del, - br_open, - br_close, - br_getflags, - br_recv, - br_send, - br_ioctl -}; - +const struct diag_l0 diag_l0_br = {"B. Roadman BR-1 interface", + "BR1", + DIAG_L1_J1850_VPW | DIAG_L1_J1850_PWM | + DIAG_L1_ISO9141 | DIAG_L1_ISO14230, + br_init, + br_new, + br_getcfg, + br_del, + br_open, + br_close, + br_getflags, + br_recv, + br_send, + br_ioctl}; diff --git a/scantool/diag_l0_dumb.c b/scantool/diag_l0_dumb.c index def3cca5..0aa63263 100644 --- a/scantool/diag_l0_dumb.c +++ b/scantool/diag_l0_dumb.c @@ -29,7 +29,6 @@ * to enable certain features (L line on RTS, etc) */ - #include #include @@ -41,8 +40,8 @@ #include "diag_l1.h" struct dumb_device { - int protocol; //set in dumb_open with specified iProtocol - struct diag_serial_settings serial; + int protocol; // set in dumb_open with specified iProtocol + struct diag_serial_settings serial; /* "dumbopts" flags. */ /* Using a struct cfgi for each of these really seems like overkill... @@ -50,69 +49,78 @@ struct dumb_device { * these flags in dumb_open(). Hence, the shortname + descriptions defined here are * unused for the moment. */ - bool use_L; - #define DD_USEL "Use RTS to drive the L line for init. Interface must support this." - #define DS_USEL "USEL" - bool clr_dtr; - #define DD_CLRDTR "Always keep DTR cleared (neg. voltage). Unusual." - #define DS_CLRDTR "CLRDTR" - bool set_rts; - #define DD_SETRTS "Always keep RTS set (pos. voltage). Unusual; do not use with USE_L." - #define DS_SETRTS "SETRTS" - bool man_break; - #define DD_MANBRK "Send manual breaks (essential for USB-serial ICs that don't support 5bps.)" - #define DS_MANBRK "MANBRK" - bool lline_inv; - #define DD_INVL "Invert polarity of the L line. Unusual." - #define DS_INVL "INVL" - bool fast_break; - #define DD_FASTBK "Try alternate iso14230 fastinit code." - #define DS_FASTBK "FASTB" - bool blockduplex; - #define DD_BKDUPX "Use message-based half duplex removal if P4==0." - #define DS_BKDUPX "BLKDUP" - - struct cfgi port; - struct cfgi dumbopts; - #define DUMBOPTS_SN "dumbopts" - #define DUMBOPTS_DESC "Dumb interface option flags; addition of the desired flags:\n" \ - " 0x01 : USE_LLINE : use if the L line (driven by RTS) is required for init. Interface must support this\n" \ - "\t(VAGTOOL for example).\n" \ - " 0x02 : CLEAR_DTR : use if your interface needs DTR to be always clear (neg. voltage).\n" \ - "\tThis is unusual. By default DTR will always be SET (pos. voltage)\n" \ - " 0x04 : SET_RTS : use if your interface needs RTS to be always set (pos. voltage).\n" \ - "\tThis is unusual. By default RTS will always be CLEAR (neg. voltage)\n" \ - "\tThis option should not be used with USE_LLINE.\n" \ - " 0x08 : MAN_BREAK : essential for USB-serial converters that don't support 5bps\n" \ - "\tsuch as FTDI232*, P230* and other ICs (enabled by default).\n" \ - " 0x10: LLINE_INV : Invert polarity of the L line. see\n" \ - "\tdoc/dumb_interfaces.txt !! This is unusual.\n" \ - " 0x20: FAST_BREAK : use alternate iso14230 fastinit code.\n" \ - " 0x40: BLOCKDUPLEX : use message-based half duplex removal (if P4==0)\n\n" \ - "ex.: \"dumbopts 9\" for MAN_BREAK and USE_LLINE.\n" - - - ttyp *tty_int; /** handle for tty stuff */ - + bool use_L; +#define DD_USEL "Use RTS to drive the L line for init. Interface must support this." +#define DS_USEL "USEL" + bool clr_dtr; +#define DD_CLRDTR "Always keep DTR cleared (neg. voltage). Unusual." +#define DS_CLRDTR "CLRDTR" + bool set_rts; +#define DD_SETRTS "Always keep RTS set (pos. voltage). Unusual; do not use with USE_L." +#define DS_SETRTS "SETRTS" + bool man_break; +#define DD_MANBRK \ + "Send manual breaks (essential for USB-serial ICs that don't support 5bps.)" +#define DS_MANBRK "MANBRK" + bool lline_inv; +#define DD_INVL "Invert polarity of the L line. Unusual." +#define DS_INVL "INVL" + bool fast_break; +#define DD_FASTBK "Try alternate iso14230 fastinit code." +#define DS_FASTBK "FASTB" + bool blockduplex; +#define DD_BKDUPX "Use message-based half duplex removal if P4==0." +#define DS_BKDUPX "BLKDUP" + + struct cfgi port; + struct cfgi dumbopts; +#define DUMBOPTS_SN "dumbopts" +#define DUMBOPTS_DESC \ + "Dumb interface option flags; addition of the desired flags:\n" \ + " 0x01 : USE_LLINE : use if the L line (driven by RTS) is required for init. " \ + "Interface must support this\n" \ + "\t(VAGTOOL for example).\n" \ + " 0x02 : CLEAR_DTR : use if your interface needs DTR to be always clear (neg. " \ + "voltage).\n" \ + "\tThis is unusual. By default DTR will always be SET (pos. voltage)\n" \ + " 0x04 : SET_RTS : use if your interface needs RTS to be always set (pos. " \ + "voltage).\n" \ + "\tThis is unusual. By default RTS will always be CLEAR (neg. voltage)\n" \ + "\tThis option should not be used with USE_LLINE.\n" \ + " 0x08 : MAN_BREAK : essential for USB-serial converters that don't support " \ + "5bps\n" \ + "\tsuch as FTDI232*, P230* and other ICs (enabled by default).\n" \ + " 0x10: LLINE_INV : Invert polarity of the L line. see\n" \ + "\tdoc/dumb_interfaces.txt !! This is unusual.\n" \ + " 0x20: FAST_BREAK : use alternate iso14230 fastinit code.\n" \ + " 0x40: BLOCKDUPLEX : use message-based half duplex removal (if P4==0)\n\n" \ + "ex.: \"dumbopts 9\" for MAN_BREAK and USE_LLINE.\n" + + ttyp *tty_int; /** handle for tty stuff */ }; - -#define BPS_PERIOD 198 //length of 5bps bits. The idea is to make this configurable eventually by adding a user-settable offset -#define WUPFLUSH 10 //should be between 5 and ~15 ms; this is the time we allow diag_tty_read to purge the break after a fast init -#define WUPOFFSET 2 //shorten fastinit wake-up pattern by WUPOFFSET ms, to fine-tune tWUP. Another ugly bandaid that should be - //at least runtime-configurable +#define BPS_PERIOD \ + 198 // length of 5bps bits. The idea is to make this configurable eventually by + // adding a user-settable offset +#define WUPFLUSH \ + 10 // should be between 5 and ~15 ms; this is the time we allow diag_tty_read to + // purge the break after a fast init +#define WUPOFFSET \ + 2 // shorten fastinit wake-up pattern by WUPOFFSET ms, to fine-tune tWUP. Another + // ugly bandaid that should be at least runtime-configurable // dumbopts flags set according to particular interface type (VAGtool vs SE etc.) -#define USE_LLINE 0x01 //interface maps L line to RTS : setting RTS normally pulls L down to 0 . -#define CLEAR_DTR 0x02 //have DTR cleared constantly (unusual, disabled by default) -#define SET_RTS 0x04 //have RTS set constantly (also unusual, disabled by default). -#define MAN_BREAK 0x08 //force bitbanged breaks for inits; enabled by default -#define LLINE_INV 0x10 //invert polarity of the L line if set. see doc/dumb_interfaces.txt -#define FAST_BREAK 0x20 //do we use diag_tty_fastbreak for iso14230-style fast init. -#define BLOCKDUPLEX 0x40 //This allows half duplex removal on a whole message if P4==0 (see diag_l1_send()) -#define DUMBDEFAULTS (MAN_BREAK | BLOCKDUPLEX) //default set of flags - - +#define USE_LLINE \ + 0x01 // interface maps L line to RTS : setting RTS normally pulls L down to 0 . +#define CLEAR_DTR 0x02 // have DTR cleared constantly (unusual, disabled by default) +#define SET_RTS 0x04 // have RTS set constantly (also unusual, disabled by default). +#define MAN_BREAK 0x08 // force bitbanged breaks for inits; enabled by default +#define LLINE_INV 0x10 // invert polarity of the L line if set. see doc/dumb_interfaces.txt +#define FAST_BREAK 0x20 // do we use diag_tty_fastbreak for iso14230-style fast init. +#define BLOCKDUPLEX \ + 0x40 // This allows half duplex removal on a whole message if P4==0 (see + // diag_l1_send()) +#define DUMBDEFAULTS (MAN_BREAK | BLOCKDUPLEX) // default set of flags extern const struct diag_l0 diag_l0_dumb; @@ -142,7 +150,7 @@ dumb_new(struct diag_l0_device *dl0d) { } dl0d->l0_int = dev; - + rv = diag_cfgn_tty(&dev->port); if (rv != 0) { free(dev); @@ -163,13 +171,14 @@ dumb_new(struct diag_l0_device *dl0d) { dev->dumbopts.next = NULL; printf("Note concerning generic (dumb) interfaces : there are additional\n" - "options which can be set with \"set dumbopts\". By default\n" - "\"K-line only\" and \"MAN_BREAK\" are set. \n"); + "options which can be set with \"set dumbopts\". By default\n" + "\"K-line only\" and \"MAN_BREAK\" are set. \n"); return 0; } -static void dumb_del(struct diag_l0_device *dl0d) { +static void +dumb_del(struct diag_l0_device *dl0d) { struct dumb_device *dev; assert(dl0d); @@ -185,7 +194,8 @@ static void dumb_del(struct diag_l0_device *dl0d) { return; } -static struct cfgi *dumb_getcfg(struct diag_l0_device *dl0d) { +static struct cfgi * +dumb_getcfg(struct diag_l0_device *dl0d) { struct dumb_device *dev; if (dl0d == NULL) { return diag_pseterr(DIAG_ERR_BADCFG); @@ -195,17 +205,17 @@ static struct cfgi *dumb_getcfg(struct diag_l0_device *dl0d) { return &dev->port; } - -static int dumb_open(struct diag_l0_device *dl0d, int iProtocol) { +static int +dumb_open(struct diag_l0_device *dl0d, int iProtocol) { struct dumb_device *dev; int dumbopts; assert(dl0d); dev = dl0d->l0_int; - if (diag_l0_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "open port %s L1proto %d\n", - FL, dev->port.val.str, iProtocol); + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "open port %s L1proto %d\n", FL, dev->port.val.str, + iProtocol); } /* try to open TTY */ @@ -236,14 +246,14 @@ static int dumb_open(struct diag_l0_device *dl0d, int iProtocol) { return diag_iseterr(DIAG_ERR_GENERAL); } - (void)diag_tty_iflush(dev->tty_int); /* Flush unread input */ + (void)diag_tty_iflush(dev->tty_int); /* Flush unread input */ dl0d->opened = 1; return 0; } -//dumb_close : close TTY handle. +// dumb_close : close TTY handle. static void dumb_close(struct diag_l0_device *dl0d) { if (!dl0d) { @@ -252,7 +262,7 @@ dumb_close(struct diag_l0_device *dl0d) { struct dumb_device *dev = dl0d->l0_int; - if (diag_l0_debug & DIAG_DEBUG_CLOSE) { + if (diag_l0_debug_load() & DIAG_DEBUG_CLOSE) { fprintf(stderr, FLFMT "l0 link %p closing\n", FL, (void *)dl0d); } @@ -273,76 +283,83 @@ dumb_close(struct diag_l0_device *dl0d) { static int dumb_fastinit(struct diag_l0_device *dl0d) { struct dumb_device *dev = dl0d->l0_int; - int rv=0; + int rv = 0; uint8_t cbuf[MAXRBUF]; - if (diag_l0_debug & DIAG_DEBUG_INIT) { + if (diag_l0_debug_load() & DIAG_DEBUG_INIT) { fprintf(stderr, FLFMT "dl0d=%p fastinit\n", FL, (void *)dl0d); } - //Tidle before break : W5 (>300ms) on poweron; P3 (>55ms) after a StopCommunication; or 0ms after a P3 timeout. + // Tidle before break : W5 (>300ms) on poweron; P3 (>55ms) after a + // StopCommunication; or 0ms after a P3 timeout. // We assume the caller took care of this. /* Send 25/25 ms break as initialisation pattern (TiniL) */ - //ISO14230-2 says we should send the same sync pattern on both L and K together. - // we do it almost perfectly; the L \_/ pulse starts before and ends after the K \_/ pulse. + // ISO14230-2 says we should send the same sync pattern on both L and K together. + // we do it almost perfectly; the L \_/ pulse starts before and ends after the K + // \_/ pulse. if (dev->use_L) { // do K+L only if the user wants to do both if (dev->fast_break) { - //but we can't use diag_tty_fastbreak while doing the L-line. - fprintf(stderr, FLFMT "Warning : not using L line for FAST_BREAK.\n", FL); - rv=diag_tty_fastbreak(dev->tty_int, 50-WUPFLUSH); + // but we can't use diag_tty_fastbreak while doing the L-line. + fprintf(stderr, + FLFMT "Warning : not using L line for FAST_BREAK.\n", FL); + rv = diag_tty_fastbreak(dev->tty_int, 50 - WUPFLUSH); } else { - unsigned long long tb0,tb1; //WUP adjustment - //normal fast break on K and L. - //note : if LLINE_INV is 1, then we need to clear RTS to pull L down ! - if (diag_tty_control(dev->tty_int, !(dev->clr_dtr), !(dev->lline_inv)) < 0) { - fprintf(stderr, FLFMT "fastinit: Failed to set L\\_\n", FL); + unsigned long long tb0, tb1; // WUP adjustment + // normal fast break on K and L. + // note : if LLINE_INV is 1, then we need to clear RTS to pull L + // down ! + if (diag_tty_control(dev->tty_int, !(dev->clr_dtr), + !(dev->lline_inv)) < 0) { + fprintf(stderr, FLFMT "fastinit: Failed to set L\\_\n", + FL); return DIAG_ERR_GENERAL; - } + } tb0 = diag_os_gethrt(); - rv=diag_tty_break(dev->tty_int, 25); //K line low for 25ms - /* Now restore DTR/RTS */ - if (diag_tty_control(dev->tty_int, !(dev->clr_dtr), dev->set_rts) < 0) { - fprintf(stderr, FLFMT "fastinit: Failed to restore DTR & RTS!\n", + rv = diag_tty_break(dev->tty_int, 25); // K line low for 25ms + /* Now restore DTR/RTS */ + if (diag_tty_control(dev->tty_int, !(dev->clr_dtr), dev->set_rts) < + 0) { + fprintf(stderr, + FLFMT "fastinit: Failed to restore DTR & RTS!\n", FL); } tb1 = diag_os_gethrt() - tb0; - tb1 = diag_os_hrtus(tb1)/1000; //elapsed ms so far within tWUP - tb1 = (50 - WUPFLUSH) - tb1; //remaining time in WUP + tb1 = diag_os_hrtus(tb1) / 1000; // elapsed ms so far within tWUP + tb1 = (50 - WUPFLUSH) - tb1; // remaining time in WUP if (tb1 > 25) { return DIAG_ERR_GENERAL; // should never happen // ! } - diag_os_millisleep((unsigned int) tb1); - } //if FAST_BREAK + diag_os_millisleep((unsigned int)tb1); + } // if FAST_BREAK } else { // do K line only if (dev->fast_break) { - rv=diag_tty_fastbreak(dev->tty_int, 50-WUPFLUSH); + rv = diag_tty_fastbreak(dev->tty_int, 50 - WUPFLUSH); } else { - //normal break - unsigned long long tb0,tb1; //WUP adjustment + // normal break + unsigned long long tb0, tb1; // WUP adjustment tb0 = diag_os_gethrt(); - rv=diag_tty_break(dev->tty_int, 25); //K line low for 25ms + rv = diag_tty_break(dev->tty_int, 25); // K line low for 25ms tb1 = diag_os_gethrt() - tb0; - tb1 = diag_os_hrtus(tb1)/1000; //elapsed ms so far within tWUP - tb1 = (50 - WUPFLUSH) - tb1; //remaining time in WUP + tb1 = diag_os_hrtus(tb1) / 1000; // elapsed ms so far within tWUP + tb1 = (50 - WUPFLUSH) - tb1; // remaining time in WUP if (tb1 > 25) { return DIAG_ERR_GENERAL; // should never happen // ! } - diag_os_millisleep((unsigned int) tb1); + diag_os_millisleep((unsigned int)tb1); } - } //if USE_LLINE + } // if USE_LLINE // here we have WUPFLUSH ms before tWUP is done; we use this // short time to flush RX buffers. (L2 needs to send a StartComm // request very soon.) diag_tty_read(dev->tty_int, cbuf, sizeof(cbuf), WUPFLUSH); - - //there may have been a problem in diag_tty_break, if so : + // there may have been a problem in diag_tty_break, if so : if (rv) { fprintf(stderr, FLFMT " L0 fastinit : problem !\n", FL); return DIAG_ERR_GENERAL; @@ -350,11 +367,11 @@ dumb_fastinit(struct diag_l0_device *dl0d) { return 0; } - /* Do the 5 BAUD L line stuff while the K line is twiddling */ // Only called from slowinit if USE_LLINE && !MAN_BREAK. // Caller must have waited before calling; DTR and RTS should be set correctly beforehand. -// Returns after stop bit is finished + time for diag_tty_read to flush echo. (max 20ms) (NOT the sync byte!) +// Returns after stop bit is finished + time for diag_tty_read to flush echo. (max 20ms) +// (NOT the sync byte!) static void dumb_Lline(struct diag_l0_device *dl0d, uint8_t ecuaddr) { @@ -363,9 +380,9 @@ dumb_Lline(struct diag_l0_device *dl0d, uint8_t ecuaddr) { * 8 bit ecuaddr at 5 baud LSB first * */ - int i, rv=0; + int i, rv = 0; struct dumb_device *dev = dl0d->l0_int; -// uint8_t cbuf[10]; + // uint8_t cbuf[10]; // We also toggle DTR to disable RXD (blocking it at logical 1). // However, at least one system I tested doesn't react well to @@ -375,40 +392,40 @@ dumb_Lline(struct diag_l0_device *dl0d, uint8_t ecuaddr) { fprintf(stderr, FLFMT "_LLine: Failed to set DTR & RTS\n", FL); return; } - diag_os_millisleep(BPS_PERIOD); /* 200ms -5% */ + diag_os_millisleep(BPS_PERIOD); /* 200ms -5% */ - for (i=0; i<8; i++) { - if (ecuaddr & (1<tty_int, (dev->clr_dtr), (dev->lline_inv)); + rv |= diag_tty_control(dev->tty_int, (dev->clr_dtr), + (dev->lline_inv)); } else { /* Low */ - rv |= diag_tty_control(dev->tty_int, (dev->clr_dtr), !(dev->lline_inv)); + rv |= diag_tty_control(dev->tty_int, (dev->clr_dtr), + !(dev->lline_inv)); } if (rv < 0) { - fprintf(stderr, FLFMT "_LLine: Failed to set DTR & RTS\n", - FL); + fprintf(stderr, FLFMT "_LLine: Failed to set DTR & RTS\n", FL); return; } - diag_os_millisleep(BPS_PERIOD); /* 200ms -5% */ + diag_os_millisleep(BPS_PERIOD); /* 200ms -5% */ } /* And set high for the stop bit */ if (diag_tty_control(dev->tty_int, (dev->clr_dtr), !(dev->lline_inv)) < 0) { - fprintf(stderr, FLFMT "_LLine: Failed to set DTR & RTS\n", - FL); + fprintf(stderr, FLFMT "_LLine: Failed to set DTR & RTS\n", FL); return; } - diag_os_millisleep(BPS_PERIOD); /* 200ms -5% */ + diag_os_millisleep(BPS_PERIOD); /* 200ms -5% */ /* Now put DTR/RTS back correctly so RX side is enabled */ if (diag_tty_control(dev->tty_int, !(dev->clr_dtr), dev->set_rts) < 0) { - fprintf(stderr, FLFMT "_LLine: Failed to restore DTR & RTS\n", - FL); + fprintf(stderr, FLFMT "_LLine: Failed to restore DTR & RTS\n", FL); } - /* And clear out the break XXX no, _slowinit will do this for us after calling dumb_Lline*/ -// diag_tty_read(dev->tty_int, cbuf, sizeof(cbuf), 20); + /* And clear out the break XXX no, _slowinit will do this for us after calling + * dumb_Lline*/ + // diag_tty_read(dev->tty_int, cbuf, sizeof(cbuf), 20); return; } @@ -427,72 +444,78 @@ dumb_Lline(struct diag_l0_device *dl0d, uint8_t ecuaddr) { */ static int dumb_slowinit(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in, - struct dumb_device *dev) { + struct dumb_device *dev) { uint8_t cbuf[10]; int rv; unsigned int tout; struct diag_serial_settings set; - if (diag_l0_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "slowinit dl0d=%p address 0x%X\n", - FL, (void *)dl0d, in->addr); + if (diag_l0_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "slowinit dl0d=%p address 0x%X\n", FL, (void *)dl0d, + in->addr); } - - //two methods of sending at 5bps. Most USB-serial converts don't support such a slow bitrate ! + // two methods of sending at 5bps. Most USB-serial converts don't support such a + // slow bitrate ! if (dev->man_break) { - //MAN_BREAK means we bitbang 5bps init on K and optionally L as well. + // MAN_BREAK means we bitbang 5bps init on K and optionally L as well. - //send the byte at in->addr, bit by bit. + // send the byte at in->addr, bit by bit. int bitcounter; - uint8_t tempbyte=in->addr; - bool curbit = 0; //startbit - for (bitcounter=0; bitcounter<=8; bitcounter++) { - //LSB first. + uint8_t tempbyte = in->addr; + bool curbit = 0; // startbit + for (bitcounter = 0; bitcounter <= 8; bitcounter++) { + // LSB first. if (curbit) { if (dev->use_L) { - //release L - diag_tty_control(dev->tty_int, !(dev->clr_dtr), (dev->lline_inv)); + // release L + diag_tty_control(dev->tty_int, !(dev->clr_dtr), + (dev->lline_inv)); } diag_os_millisleep(BPS_PERIOD); } else { - unsigned int lowtime=BPS_PERIOD; - //to prevent spurious breaks if we have a sequence of 0's : - //this is an RLE of sorts... - for (; bitcounter <=7; bitcounter++) { - if (tempbyte & - 1) { // test bit 1; we just tested - // curbit before getting here. + unsigned int lowtime = BPS_PERIOD; + // to prevent spurious breaks if we have a sequence of 0's + // : this is an RLE of sorts... + for (; bitcounter <= 7; bitcounter++) { + if (tempbyte & 1) { // test bit 1; we just tested + // curbit before getting here. break; } lowtime += BPS_PERIOD; curbit = tempbyte & 1; - tempbyte = tempbyte >>1; + tempbyte = tempbyte >> 1; } - //this way, we know for sure the next bit is 1 (either bit 7==1 or stopbit==1 !) + // this way, we know for sure the next bit is 1 (either bit + // 7==1 or stopbit==1 !) if (dev->use_L) { - //L = 0 - diag_tty_control(dev->tty_int, !(dev->clr_dtr), !(dev->lline_inv)); + // L = 0 + diag_tty_control(dev->tty_int, !(dev->clr_dtr), + !(dev->lline_inv)); } diag_tty_break(dev->tty_int, lowtime); } curbit = tempbyte & 1; - tempbyte = tempbyte >>1; + tempbyte = tempbyte >> 1; } - //at this point we just finished the last bit, we'll wait the duration of the stop bit. + // at this point we just finished the last bit, we'll wait the duration of + // the stop bit. if (dev->use_L) { - diag_tty_control(dev->tty_int, !(dev->clr_dtr), dev->set_rts); //release L + diag_tty_control(dev->tty_int, !(dev->clr_dtr), + dev->set_rts); // release L } - diag_os_millisleep(BPS_PERIOD); //stop bit + diag_os_millisleep(BPS_PERIOD); // stop bit - //at this point the stop bit just finished. We could just purge the input buffer ? - //Usually the next thing to happen is the ECU will send the sync byte (0x55) within W1 + // at this point the stop bit just finished. We could just purge the input + // buffer ? Usually the next thing to happen is the ECU will send the sync + // byte (0x55) within W1 // (60 to 300ms) // so we have 60ms to diag_tty_iflush, the risk is if it takes too long // the "sync pattern byte" may be lost ! - // TODO : add before+after timing check to see if diag_tty_iflush takes too long - diag_tty_iflush(dev->tty_int); //try it anyway - } else { //so it's not a man_break + // TODO : add before+after timing check to see if diag_tty_iflush takes too + // long + diag_tty_iflush(dev->tty_int); // try it anyway + } else { // so it's not a man_break /* Set to 5 baud, 8 N 1 */ set.speed = 5; @@ -502,21 +525,24 @@ dumb_slowinit(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in, diag_tty_setup(dev->tty_int, &set); - /* Send the address as a single byte message */ diag_tty_write(dev->tty_int, &in->addr, 1); - //This supposes that diag_tty_write is non-blocking, i.e. returns before write is complete ! + // This supposes that diag_tty_write is non-blocking, i.e. returns before + // write is complete ! // 8 bits + start bit + stop bit @ 5bps = 2000 ms /* Do the L line stuff as required*/ if (dev->use_L) { dumb_Lline(dl0d, in->addr); - tout=400; //Shorter timeout to get back echo, as dumb_Lline exits after 5bps stopbit. + tout = 400; // Shorter timeout to get back echo, as dumb_Lline + // exits after 5bps stopbit. } else { - // If there's no manual L line to do, timeout needs to be longer to receive echo - tout=2400; + // If there's no manual L line to do, timeout needs to be longer to + // receive echo + tout = 2400; } - //TODO : try with diag_tty_iflush instead of trying to read a single echo byte? - //I expect the RX buffer might have more than 1 spurious byte in it at this point... + // TODO : try with diag_tty_iflush instead of trying to read a single echo + // byte? I expect the RX buffer might have more than 1 spurious byte in it + // at this point... /* * And read back the single byte echo, which shows TX completes * - At 5 baud, it takes 2 seconds to send a byte .. @@ -525,24 +551,26 @@ dumb_slowinit(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in, * echo */ - if (diag_tty_read(dev->tty_int, cbuf, 1,tout) != 1) { + if (diag_tty_read(dev->tty_int, cbuf, 1, tout) != 1) { fprintf(stderr, FLFMT "_slowinit: address echo error\n", FL); return DIAG_ERR_GENERAL; } - if (diag_l0_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "\tgot address echo 0x%X\n", FL, - cbuf[0]); + if (diag_l0_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "\tgot address echo 0x%X\n", FL, cbuf[0]); } if (diag_tty_setup(dev->tty_int, &dev->serial)) { - //reset original settings - fprintf(stderr, FLFMT "_slowinit: could not reset serial settings !\n", FL); + // reset original settings + fprintf(stderr, + FLFMT "_slowinit: could not reset serial settings !\n", + FL); return DIAG_ERR_GENERAL; } - } //if !man_break - //Here, we sent 0x33 @ 5bps and read back the echo or purged it. - diag_os_millisleep(60-IFLUSH_TIMEOUT); //W1 minimum, less the time we spend in diag_tty_iflush - //Now the ECU is about to, or already, sending the sync byte 0x55. + } // if !man_break + // Here, we sent 0x33 @ 5bps and read back the echo or purged it. + diag_os_millisleep(60 - IFLUSH_TIMEOUT); // W1 minimum, less the time we spend in + // diag_tty_iflush + // Now the ECU is about to, or already, sending the sync byte 0x55. /* * Ideally we would now measure the length of the received * 0x55 sync byte to work out the baud rate. @@ -561,30 +589,31 @@ dumb_slowinit(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in, */ if (dev->protocol == DIAG_L1_ISO9141) { - tout = 241+50; /* maximum W1 + sync byte@10kbps - elapsed (60ms) + mud factor= 241ms + mud factor*/ - } else if (dev->protocol== DIAG_L1_ISO14230) { + tout = 241 + 50; /* maximum W1 + sync byte@10kbps - elapsed (60ms) + mud + factor= 241ms + mud factor*/ + } else if (dev->protocol == DIAG_L1_ISO14230) { // probably ISO14230-2 sec 5.2.4.2.2 - tout = 300; /* It should be the same thing, but let's put 300. */ + tout = 300; /* It should be the same thing, but let's put 300. */ } else { - fprintf(stderr, FLFMT "warning : using Slowinit with a strange L1 protocol !\n", FL); - tout=300; //but try anyway + fprintf(stderr, + FLFMT "warning : using Slowinit with a strange L1 protocol !\n", + FL); + tout = 300; // but try anyway } rv = diag_tty_read(dev->tty_int, cbuf, 1, tout); if (rv <= 0) { - if (diag_l0_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "\tdid not get Sync byte !\n", - FL); + if (diag_l0_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "\tdid not get Sync byte !\n", FL); } return DIAG_ERR_TIMEOUT; } - if (diag_l0_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "\tgot sync byte 0x%X!\n", FL, - cbuf[0]); + if (diag_l0_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "\tgot sync byte 0x%X!\n", FL, cbuf[0]); } - //If all's well at this point, we just read the sync pattern byte. L2 will take care - //of reading + echoing the keybytes + // If all's well at this point, we just read the sync pattern byte. L2 will take + // care of reading + echoing the keybytes return 0; } @@ -602,9 +631,8 @@ dumb_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { dev = (struct dumb_device *)dl0d->l0_int; - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { - fprintf(stderr, - FLFMT "device link %p info %p initbus type %d\n", FL, + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { + fprintf(stderr, FLFMT "device link %p info %p initbus type %d\n", FL, (void *)dl0d, (void *)dev, in->type); } @@ -612,34 +640,32 @@ dumb_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { return diag_iseterr(DIAG_ERR_GENERAL); } - (void)diag_tty_iflush(dev->tty_int); /* Flush unread input */ + (void)diag_tty_iflush(dev->tty_int); /* Flush unread input */ switch (in->type) { - case DIAG_L1_INITBUS_FAST: - rv = dumb_fastinit(dl0d); - break; - case DIAG_L1_INITBUS_5BAUD: - rv = dumb_slowinit(dl0d, in, dev); - break; - case DIAG_L1_INITBUS_2SLOW: - // iso 9141 - 1989 style init, not implemented. - default: - rv = DIAG_ERR_INIT_NOTSUPP; - break; + case DIAG_L1_INITBUS_FAST: + rv = dumb_fastinit(dl0d); + break; + case DIAG_L1_INITBUS_5BAUD: + rv = dumb_slowinit(dl0d, in, dev); + break; + case DIAG_L1_INITBUS_2SLOW: + // iso 9141 - 1989 style init, not implemented. + default: + rv = DIAG_ERR_INIT_NOTSUPP; + break; } - if (rv) { fprintf(stderr, FLFMT "L0 initbus failed with %d\n", FL, rv); return diag_iseterr(rv); } return 0; - } - -static int dumb_iflush(struct diag_l0_device *dl0d) { +static int +dumb_iflush(struct diag_l0_device *dl0d) { struct dumb_device *dev = dl0d->l0_int; return diag_tty_iflush(dev->tty_int); @@ -653,9 +679,8 @@ static int dumb_iflush(struct diag_l0_device *dl0d) { */ static int -dumb_send(struct diag_l0_device *dl0d, -UNUSED(const char *subinterface), -const void *data, size_t len) { +dumb_send(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), const void *data, + size_t len) { /* * This will be called byte at a time unless P4 timing parameter is zero * as the L1 code that called this will be adding the P4 gap between @@ -668,16 +693,16 @@ const void *data, size_t len) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l0_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "l0_send dl0d=%p len=%ld; ", - FL, (void *)dl0d, (long)len); - if (diag_l0_debug & DIAG_DEBUG_DATA) { + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "l0_send dl0d=%p len=%ld; ", FL, (void *)dl0d, + (long)len); + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { diag_data_dump(stderr, data, len); } fprintf(stderr, "\n"); } - if ((rv = diag_tty_write(dev->tty_int, data, len)) != (int) len) { + if ((rv = diag_tty_write(dev->tty_int, data, len)) != (int)len) { fprintf(stderr, FLFMT "dumb_send: write error\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } @@ -692,9 +717,8 @@ const void *data, size_t len) { */ static int -dumb_recv(struct diag_l0_device *dl0d, -UNUSED(const char *subinterface), -void *data, size_t len, unsigned int timeout) { +dumb_recv(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), void *data, + size_t len, unsigned int timeout) { int rv; struct dumb_device *dev = dl0d->l0_int; @@ -702,20 +726,19 @@ void *data, size_t len, unsigned int timeout) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l0_debug & DIAG_DEBUG_READ) { - fprintf(stderr, - FLFMT "_recv dl0d=%p req=%ld bytes timeout=%u\n", FL, + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "_recv dl0d=%p req=%ld bytes timeout=%u\n", FL, (void *)dl0d, (long)len, timeout); } - if ((rv=diag_tty_read(dev->tty_int, data, len, timeout)) <= 0) { + if ((rv = diag_tty_read(dev->tty_int, data, len, timeout)) <= 0) { if (rv == DIAG_ERR_TIMEOUT) { return DIAG_ERR_TIMEOUT; } return diag_iseterr(DIAG_ERR_GENERAL); } - if ((diag_l0_debug & DIAG_DEBUG_DATA) && (diag_l0_debug & DIAG_DEBUG_READ)) { + if (diag_l0_debug_load() & (DIAG_DEBUG_DATA | DIAG_DEBUG_READ)) { fprintf(stderr, FLFMT "Got ", FL); diag_data_dump(stderr, data, (size_t)rv); fprintf(stderr, "\n"); @@ -728,8 +751,7 @@ void *data, size_t len, unsigned int timeout) { * ret 0 if ok */ static int -dumb_setspeed(struct diag_l0_device *dl0d, -const struct diag_serial_settings *pset) { +dumb_setspeed(struct diag_l0_device *dl0d, const struct diag_serial_settings *pset) { struct dumb_device *dev; dev = (struct dumb_device *)dl0d->l0_int; @@ -739,11 +761,10 @@ const struct diag_serial_settings *pset) { return diag_tty_setup(dev->tty_int, &dev->serial); } - static uint32_t dumb_getflags(struct diag_l0_device *dl0d) { struct dumb_device *dev; - int flags=0; + int flags = 0; dev = (struct dumb_device *)dl0d->l0_int; @@ -753,7 +774,8 @@ dumb_getflags(struct diag_l0_device *dl0d) { switch (dev->protocol) { case DIAG_L1_ISO14230: - flags |= DIAG_L1_FAST | DIAG_L1_PREFFAST | DIAG_L1_SLOW | DIAG_L1_HALFDUPLEX; + flags |= DIAG_L1_FAST | DIAG_L1_PREFFAST | DIAG_L1_SLOW | + DIAG_L1_HALFDUPLEX; break; case DIAG_L1_ISO9141: flags |= DIAG_L1_SLOW | DIAG_L1_HALFDUPLEX; @@ -765,12 +787,13 @@ dumb_getflags(struct diag_l0_device *dl0d) { return flags; } -static int dumb_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { +static int +dumb_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { int rv = 0; switch (cmd) { case DIAG_IOCTL_SETSPEED: - rv = dumb_setspeed(dl0d, (const struct diag_serial_settings *) data); + rv = dumb_setspeed(dl0d, (const struct diag_serial_settings *)data); break; case DIAG_IOCTL_INITBUS: rv = dumb_initbus(dl0d, (struct diag_l1_initbus_args *)data); @@ -786,9 +809,8 @@ static int dumb_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { return rv; } - const struct diag_l0 diag_l0_dumb = { - "Generic dumb serial interface", + "Generic dumb serial interface", "DUMB", DIAG_L1_ISO9141 | DIAG_L1_ISO14230 | DIAG_L1_RAW, dumb_init, diff --git a/scantool/diag_l0_dumbtest.c b/scantool/diag_l0_dumbtest.c index 422be64b..b0274eba 100644 --- a/scantool/diag_l0_dumbtest.c +++ b/scantool/diag_l0_dumbtest.c @@ -11,10 +11,9 @@ * before returning. */ - #include #include -#include //for memcmp +#include //for memcmp #include "diag.h" #include "diag_err.h" @@ -24,7 +23,7 @@ #include "diag_l1.h" struct dt_device { - int protocol; //set in dt_open with specified iProtocol + int protocol; // set in dt_open with specified iProtocol struct diag_serial_settings serial; /* "dumbopts" flags. Copied from l0_dumb driver */ @@ -33,69 +32,73 @@ struct dt_device { * these flags in dumb_open(). Hence, the shortname + descriptions defined here are * unused for the moment. */ - bool use_L; - #define DD_USEL "Use RTS to drive the L line for init. Interface must support this." - #define DS_USEL "USEL" - bool clr_dtr; - #define DD_CLRDTR "Always keep DTR cleared (neg. voltage). Unusual." - #define DS_CLRDTR "CLRDTR" - bool set_rts; - #define DD_SETRTS "Always keep RTS set (pos. voltage). Unusual; do not use with USE_L." - #define DS_SETRTS "SETRTS" - bool man_break; - #define DD_MANBRK "Send manual breaks (essential for USB-serial ICs that don't support 5bps.)" - #define DS_MANBRK "MANBRK" - bool lline_inv; - #define DD_INVL "Invert polarity of the L line. Unusual." - #define DS_INVL "INVL" - bool fast_break; - #define DD_FASTBK "Try alternate iso14230 fastinit code." - #define DS_FASTBK "FASTB" - bool blockduplex; - #define DD_BKDUPX "Use message-based half duplex removal if P4==0." - #define DS_BKDUPX "BLKDUP" - - struct cfgi port; - struct cfgi dumbopts; - #define DUMBOPTS_SN "dumbopts" - #define DUMBOPTS_DESC "Dumb interface option flags; addition of the desired flags:\n" \ - " 0x01 : USE_LLINE : use if the L line (driven by RTS) is required for init. Interface must support this\n" \ - "\t(VAGTOOL for example).\n" \ - " 0x02 : CLEAR_DTR : use if your interface needs DTR to be always clear (neg. voltage).\n" \ - "\tThis is unusual. By default DTR will always be SET (pos. voltage)\n" \ - " 0x04 : SET_RTS : use if your interface needs RTS to be always set (pos. voltage).\n" \ - "\tThis is unusual. By default RTS will always be CLEAR (neg. voltage)\n" \ - "\tThis option should not be used with USE_LLINE.\n" \ - " 0x08 : MAN_BREAK : essential for USB-serial converters that don't support 5bps\n" \ - "\tsuch as FTDI232*, P230* and other ICs (enabled by default).\n" \ - " 0x10: LLINE_INV : Invert polarity of the L line. see\n" \ - "\tdoc/dumb_interfaces.txt !! This is unusual.\n" \ - " 0x20: FAST_BREAK : use alternate iso14230 fastinit code.\n" \ - " 0x40: BLOCKDUPLEX : use message-based half duplex removal (if P4==0)\n\n" \ - "ex.: \"dumbopts 9\" for MAN_BREAK and USE_LLINE.\n" - - - ttyp *tty_int; /** handle for tty stuff */ + bool use_L; +#define DD_USEL "Use RTS to drive the L line for init. Interface must support this." +#define DS_USEL "USEL" + bool clr_dtr; +#define DD_CLRDTR "Always keep DTR cleared (neg. voltage). Unusual." +#define DS_CLRDTR "CLRDTR" + bool set_rts; +#define DD_SETRTS "Always keep RTS set (pos. voltage). Unusual; do not use with USE_L." +#define DS_SETRTS "SETRTS" + bool man_break; +#define DD_MANBRK \ + "Send manual breaks (essential for USB-serial ICs that don't support 5bps.)" +#define DS_MANBRK "MANBRK" + bool lline_inv; +#define DD_INVL "Invert polarity of the L line. Unusual." +#define DS_INVL "INVL" + bool fast_break; +#define DD_FASTBK "Try alternate iso14230 fastinit code." +#define DS_FASTBK "FASTB" + bool blockduplex; +#define DD_BKDUPX "Use message-based half duplex removal if P4==0." +#define DS_BKDUPX "BLKDUP" + + struct cfgi port; + struct cfgi dumbopts; +#define DUMBOPTS_SN "dumbopts" +#define DUMBOPTS_DESC \ + "Dumb interface option flags; addition of the desired flags:\n" \ + " 0x01 : USE_LLINE : use if the L line (driven by RTS) is required for init. " \ + "Interface must support this\n" \ + "\t(VAGTOOL for example).\n" \ + " 0x02 : CLEAR_DTR : use if your interface needs DTR to be always clear (neg. " \ + "voltage).\n" \ + "\tThis is unusual. By default DTR will always be SET (pos. voltage)\n" \ + " 0x04 : SET_RTS : use if your interface needs RTS to be always set (pos. " \ + "voltage).\n" \ + "\tThis is unusual. By default RTS will always be CLEAR (neg. voltage)\n" \ + "\tThis option should not be used with USE_LLINE.\n" \ + " 0x08 : MAN_BREAK : essential for USB-serial converters that don't support " \ + "5bps\n" \ + "\tsuch as FTDI232*, P230* and other ICs (enabled by default).\n" \ + " 0x10: LLINE_INV : Invert polarity of the L line. see\n" \ + "\tdoc/dumb_interfaces.txt !! This is unusual.\n" \ + " 0x20: FAST_BREAK : use alternate iso14230 fastinit code.\n" \ + " 0x40: BLOCKDUPLEX : use message-based half duplex removal (if P4==0)\n\n" \ + "ex.: \"dumbopts 9\" for MAN_BREAK and USE_LLINE.\n" + + ttyp *tty_int; /** handle for tty stuff */ }; - // dumbopts flags set according to particular interface type (VAGtool vs SE etc.) -#define USE_LLINE 0x01 //interface maps L line to RTS : setting RTS normally pulls L down to 0 . -#define CLEAR_DTR 0x02 //have DTR cleared constantly (unusual, disabled by default) -#define SET_RTS 0x04 //have RTS set constantly (also unusual, disabled by default). -#define MAN_BREAK 0x08 //force bitbanged breaks for inits; enabled by default -#define LLINE_INV 0x10 //invert polarity of the L line if set. see doc/dumb_interfaces.txt -#define FAST_BREAK 0x20 //do we use diag_tty_fastbreak for iso14230-style fast init. -#define BLOCKDUPLEX 0x40 //This allows half duplex removal on a whole message if P4==0 (see diag_l1_send()) -#define DUMBDEFAULTS (MAN_BREAK | BLOCKDUPLEX) //default set of flags - +#define USE_LLINE \ + 0x01 // interface maps L line to RTS : setting RTS normally pulls L down to 0 . +#define CLEAR_DTR 0x02 // have DTR cleared constantly (unusual, disabled by default) +#define SET_RTS 0x04 // have RTS set constantly (also unusual, disabled by default). +#define MAN_BREAK 0x08 // force bitbanged breaks for inits; enabled by default +#define LLINE_INV 0x10 // invert polarity of the L line if set. see doc/dumb_interfaces.txt +#define FAST_BREAK 0x20 // do we use diag_tty_fastbreak for iso14230-style fast init. +#define BLOCKDUPLEX \ + 0x40 // This allows half duplex removal on a whole message if P4==0 (see + // diag_l1_send()) +#define DUMBDEFAULTS (MAN_BREAK | BLOCKDUPLEX) // default set of flags extern const struct diag_l0 diag_l0_dumbtest; -static int -dt_send(struct diag_l0_device *dl0d, -UNUSED(const char *subinterface), -const void *data, size_t len); +static int dt_send(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), + const void *data, size_t len); /* * Init must be callable even if no physical interface is @@ -105,7 +108,7 @@ const void *data, size_t len); static int dt_init(void) { /* Global init flag */ - static int dt_initdone=0; + static int dt_initdone = 0; if (dt_initdone) { return 0; @@ -118,17 +121,15 @@ dt_init(void) { return 0; } +// dtest_1 : slow pulse TXD with diag_tty_break; 400ms / 200ms cycles. - - -//dtest_1 : slow pulse TXD with diag_tty_break; 400ms / 200ms cycles. - -static void dtest_1(struct diag_l0_device *dl0d) { +static void +dtest_1(struct diag_l0_device *dl0d) { int i; struct dt_device *dev = dl0d->l0_int; fprintf(stderr, "Starting test 1: pulsing TXD=1, 1s, TXD=0, 500ms:"); - for (i=0; i<=4; i++) { + for (i = 0; i <= 4; i++) { diag_os_millisleep(1000); if (diag_tty_break(dev->tty_int, 500)) { break; @@ -139,21 +140,22 @@ static void dtest_1(struct diag_l0_device *dl0d) { return; } -//dtest_2 : fast pulse TXD by sending 0x55 @ 10.4kps with 5ms interbyte -static void dtest_2(struct diag_l0_device *dl0d) { - int i, pc=0; - const int iters=300; - uint8_t patternbyte=0x55; +// dtest_2 : fast pulse TXD by sending 0x55 @ 10.4kps with 5ms interbyte +static void +dtest_2(struct diag_l0_device *dl0d) { + int i, pc = 0; + const int iters = 300; + uint8_t patternbyte = 0x55; struct dt_device *dev = dl0d->l0_int; fprintf(stderr, "Starting test 2: sending 0x55 with P4=5ms:"); - for (i=0; i<=iters; i++) { + for (i = 0; i <= iters; i++) { if (diag_tty_write(dev->tty_int, &patternbyte, 1) != 1) { fprintf(stderr, "write error\n"); break; } - if ((10*i/iters) != pc) { - pc +=1; + if ((10 * i / iters) != pc) { + pc += 1; fprintf(stderr, "."); } diag_os_millisleep(5); @@ -162,13 +164,14 @@ static void dtest_2(struct diag_l0_device *dl0d) { return; } -//dtest_3: slow pulse RTS -static void dtest_3(struct diag_l0_device *dl0d) { +// dtest_3: slow pulse RTS +static void +dtest_3(struct diag_l0_device *dl0d) { int i; struct dt_device *dev = dl0d->l0_int; fprintf(stderr, "Starting test 3: pulsing RTS=1, 1s, RTS=0, 500ms:"); - for (i=0; i<=4; i++) { + for (i = 0; i <= 4; i++) { if (diag_tty_control(dev->tty_int, !(dev->clr_dtr), 1)) { break; } @@ -184,13 +187,14 @@ static void dtest_3(struct diag_l0_device *dl0d) { return; } -//dtest_4: slow pulse DTR -static void dtest_4(struct diag_l0_device *dl0d) { +// dtest_4: slow pulse DTR +static void +dtest_4(struct diag_l0_device *dl0d) { int i; struct dt_device *dev = dl0d->l0_int; fprintf(stderr, "Starting test 4: pulsing DTR=1, 1s, DTR=0, 500ms:"); - for (i=0; i<=4; i++) { + for (i = 0; i <= 4; i++) { if (diag_tty_control(dev->tty_int, 1, dev->set_rts)) { break; } @@ -206,22 +210,22 @@ static void dtest_4(struct diag_l0_device *dl0d) { return; } +// dtest_5 : fast pulse TXD with diag_tty_break; -//dtest_5 : fast pulse TXD with diag_tty_break; - -static void dtest_5(struct diag_l0_device *dl0d) { - int i, pc=0; +static void +dtest_5(struct diag_l0_device *dl0d) { + int i, pc = 0; struct dt_device *dev = dl0d->l0_int; - const int iters=40; + const int iters = 40; fprintf(stderr, "Starting test 5: pulsing TXD=1, 50, TXD=0, 25ms:"); - for (i=0; i<=iters; i++) { + for (i = 0; i <= iters; i++) { diag_os_millisleep(50); if (diag_tty_break(dev->tty_int, 25)) { fprintf(stderr, "break error\n"); break; } - if ((10*i/iters) != pc) { - pc +=1; + if ((10 * i / iters) != pc) { + pc += 1; fprintf(stderr, "."); } } @@ -229,20 +233,21 @@ static void dtest_5(struct diag_l0_device *dl0d) { return; } -//dtest_6 : fast pulse TXD with diag_tty_fastbreak; +// dtest_6 : fast pulse TXD with diag_tty_fastbreak; -static void dtest_6(struct diag_l0_device *dl0d) { - int i, pc=0; +static void +dtest_6(struct diag_l0_device *dl0d) { + int i, pc = 0; struct dt_device *dev = dl0d->l0_int; - const int iters=50; + const int iters = 50; fprintf(stderr, "Starting test 6: pulsing TXD=1, 50ms, TXD=0, 25ms:"); - for (i=0; i<=iters; i++) { + for (i = 0; i <= iters; i++) { if (diag_tty_fastbreak(dev->tty_int, 50)) { fprintf(stderr, "fastbreak error\n"); break; } - if ((10*i/iters) != pc) { - pc +=1; + if ((10 * i / iters) != pc) { + pc += 1; fprintf(stderr, "."); } } @@ -250,21 +255,22 @@ static void dtest_6(struct diag_l0_device *dl0d) { return; } -//dtest_7 : half duplex echo removal 1 : send bytes and remove echo -//one by one; P4=0. Print per-byte time to do this; use _dumb_send() instead +// dtest_7 : half duplex echo removal 1 : send bytes and remove echo +// one by one; P4=0. Print per-byte time to do this; use _dumb_send() instead // of diag_tty directly, like l1_send(). -static void dtest_7(struct diag_l0_device *dl0d) { - uint8_t i, pc=0, echo; - int rv, badechos=0; - unsigned long long ti, tf=0; //measure inner time +static void +dtest_7(struct diag_l0_device *dl0d) { + uint8_t i, pc = 0, echo; + int rv, badechos = 0; + unsigned long long ti, tf = 0; // measure inner time struct dt_device *dev = dl0d->l0_int; #define DT7_ITERS 100 fprintf(stderr, "Starting test 7: half duplex single echo removal:"); - for (i=0; il0_int; #define DT8_ITERS 10 fprintf(stderr, "Starting test 8: half duplex block echo removal:"); - //fill i[] first + // fill i[] first for (i = 0; i < DT8_MSIZE; i++) { tx[i] = (uint8_t)i; } - for (i=0; i<=DT8_ITERS; i++) { - ti=diag_os_gethrt(); //get starting time. + for (i = 0; i <= DT8_ITERS; i++) { + ti = diag_os_gethrt(); // get starting time. if (dt_send(dl0d, NULL, tx, DT8_MSIZE)) { break; } - rv = diag_tty_read(dev->tty_int, echo, DT8_MSIZE, 100 + 5*DT8_MSIZE); + rv = diag_tty_read(dev->tty_int, echo, DT8_MSIZE, 100 + 5 * DT8_MSIZE); if (rv != DT8_MSIZE) { fprintf(stderr, "\ndt8: tty_read rets %d.\n", rv); break; } tf = tf + diag_os_gethrt() - ti; - //check echo - if ( memcmp(tx, echo, DT8_MSIZE) == 0) { - //ok - rv=0; + // check echo + if (memcmp(tx, echo, DT8_MSIZE) == 0) { + // ok + rv = 0; } else { badechos++; } fprintf(stderr, "."); - } //for + } // for - tf = tf / (DT8_ITERS * DT8_MSIZE); //average time per byte + tf = tf / (DT8_ITERS * DT8_MSIZE); // average time per byte fprintf(stderr, "\n"); if (rv != 0) { printf("Error, test did not complete.\n"); } else { - printf("Average speed : %d us/byte. %d bad echos received.\n", (int) diag_os_hrtus(tf), badechos); + printf("Average speed : %d us/byte. %d bad echos received.\n", + (int)diag_os_hrtus(tf), badechos); } return; -} //dtest_8 +} // dtest_8 -//dtest_9 : test accuracy of read timeouts. -static void dtest_9(struct diag_l0_device *dl0d) { - #define DT9_ITERS 4 +// dtest_9 : test accuracy of read timeouts. +static void +dtest_9(struct diag_l0_device *dl0d) { +#define DT9_ITERS 4 unsigned int i; int iters; uint8_t garbage[MAXRBUF]; @@ -351,77 +360,81 @@ static void dtest_9(struct diag_l0_device *dl0d) { struct dt_device *dev = dl0d->l0_int; fprintf(stderr, "Starting test 9: checking accuracy of read timeouts:\n"); - diag_tty_iflush(dev->tty_int); //purge before starting + diag_tty_iflush(dev->tty_int); // purge before starting - for (i=10; i<=200; i += 20) { - t0=diag_os_gethrt(); - for (iters=0; iters < DT9_ITERS; iters++) { + for (i = 10; i <= 200; i += 20) { + t0 = diag_os_gethrt(); + for (iters = 0; iters < DT9_ITERS; iters++) { diag_tty_read(dev->tty_int, garbage, MAXRBUF, i); } - tf = (diag_os_gethrt() - t0) / DT9_ITERS; //average measured timeout - printf("Timeout=%d: avg=%dms\n", i, (int) (diag_os_hrtus(tf)/1000)); + tf = (diag_os_gethrt() - t0) / DT9_ITERS; // average measured timeout + printf("Timeout=%d: avg=%dms\n", i, (int)(diag_os_hrtus(tf) / 1000)); } return; -} //dtest_9 +} // dtest_9 -//dtest_10 == dtest_2 with a different speed +// dtest_10 == dtest_2 with a different speed -//dtest_11 : test incomplete read timeout (needs half-duplex connection) -static void dtest_11(struct diag_l0_device *dl0d) { - #define DT11_ITERS 4 +// dtest_11 : test incomplete read timeout (needs half-duplex connection) +static void +dtest_11(struct diag_l0_device *dl0d) { +#define DT11_ITERS 4 unsigned int i; - int iters,rv; + int iters, rv; uint8_t garbage[MAXRBUF]; unsigned long long t0, tf; struct dt_device *dev = dl0d->l0_int; - fprintf(stderr, "Starting test 11: half-duplex incomplete read timeout accuracy:\n"); - diag_tty_iflush(dev->tty_int); //purge before starting + fprintf(stderr, + "Starting test 11: half-duplex incomplete read timeout accuracy:\n"); + diag_tty_iflush(dev->tty_int); // purge before starting - for (i=10; i<=180; i += 20) { - tf=0; - for (iters=0; iters < DT11_ITERS; iters++) { + for (i = 10; i <= 180; i += 20) { + tf = 0; + for (iters = 0; iters < DT11_ITERS; iters++) { uint8_t tc = i; if ((rv = dt_send(dl0d, NULL, &tc, 1))) { goto failed; } - t0=diag_os_gethrt(); - if ((rv=diag_tty_read(dev->tty_int, garbage, MAXRBUF, i)) != 1) { + t0 = diag_os_gethrt(); + if ((rv = diag_tty_read(dev->tty_int, garbage, MAXRBUF, i)) != 1) { // failed: purge + try next timeout value - fprintf(stderr, "failed @ timeout=%d : %s\n", i, diag_errlookup(rv)); + fprintf(stderr, "failed @ timeout=%d : %s\n", i, + diag_errlookup(rv)); diag_tty_iflush(dev->tty_int); break; } tf = tf + diag_os_gethrt() - t0; } tf = tf / DT11_ITERS; - printf("Timeout=%d: avg=%dms\n", i, (int) (diag_os_hrtus(tf)/1000)); + printf("Timeout=%d: avg=%dms\n", i, (int)(diag_os_hrtus(tf) / 1000)); } return; failed: - fprintf(stderr, "Problem during test! %s\n",diag_errlookup(rv)); + fprintf(stderr, "Problem during test! %s\n", diag_errlookup(rv)); return; -} //dtest_11 +} // dtest_11 -//dtest_12 : diag_tty_write() duration -static void dtest_12(struct diag_l0_device *dl0d) { - #define DT12_ITERS 4 +// dtest_12 : diag_tty_write() duration +static void +dtest_12(struct diag_l0_device *dl0d) { +#define DT12_ITERS 4 unsigned int i; int iters; uint8_t garbage[MAXRBUF]; - unsigned long long t0, tf; //measure inner time - unsigned long long ts1, ts2; //measure overall loop + unsigned long long t0, tf; // measure inner time + unsigned long long ts1, ts2; // measure overall loop struct dt_device *dev = dl0d->l0_int; fprintf(stderr, "Starting test 12: diag_tty_write() duration:\n"); - diag_tty_iflush(dev->tty_int); //purge before starting + diag_tty_iflush(dev->tty_int); // purge before starting - for (i=1; i<=50; i += 5) { - tf=0; + for (i = 1; i <= 50; i += 5) { + tf = 0; printf("len=%d:", i); - ts1=diag_os_gethrt(); - for (iters=0; iters < DT12_ITERS; iters++) { + ts1 = diag_os_gethrt(); + for (iters = 0; iters < DT12_ITERS; iters++) { unsigned long long tt1; t0 = diag_os_gethrt(); if (dt_send(dl0d, NULL, garbage, i)) { @@ -429,12 +442,13 @@ static void dtest_12(struct diag_l0_device *dl0d) { } tt1 = diag_os_gethrt(); tf = tf + (tt1 - t0); - printf("\t%luus", (long unsigned int) (diag_os_hrtus(tt1-t0))); - (void) diag_tty_read(dev->tty_int, garbage, MAXRBUF, 5); + printf("\t%luus", (long unsigned int)(diag_os_hrtus(tt1 - t0))); + (void)diag_tty_read(dev->tty_int, garbage, MAXRBUF, 5); } - ts2= (diag_os_gethrt() - ts1) / DT12_ITERS; + ts2 = (diag_os_gethrt() - ts1) / DT12_ITERS; tf = tf / DT12_ITERS; - printf(" => avg=%dms / %dms\n", (int) (diag_os_hrtus(tf)/1000), (int) (diag_os_hrtus(ts2)/1000)); + printf(" => avg=%dms / %dms\n", (int)(diag_os_hrtus(tf) / 1000), + (int)(diag_os_hrtus(ts2) / 1000)); if (i == 1) { i = 0; } @@ -445,16 +459,18 @@ static void dtest_12(struct diag_l0_device *dl0d) { return; } -//dtest_13 : simulate 14230 fastinit : 25ms low, tWUP=50ms, then send 0xAA @ 10.4k; with diag_tty_fastbreak +// dtest_13 : simulate 14230 fastinit : 25ms low, tWUP=50ms, then send 0xAA @ 10.4k; with +// diag_tty_fastbreak -static void dtest_13(struct diag_l0_device *dl0d) { - int i, pc=0; - const int iters=50; - const uint8_t db=0xAA; +static void +dtest_13(struct diag_l0_device *dl0d) { + int i, pc = 0; + const int iters = 50; + const uint8_t db = 0xAA; struct dt_device *dev = dl0d->l0_int; fprintf(stderr, "Starting test 6: simulate fastinit:"); - for (i=0; i<=iters; i++) { + for (i = 0; i <= iters; i++) { if (diag_tty_fastbreak(dev->tty_int, 50)) { fprintf(stderr, "fastbreak error\n"); break; @@ -463,9 +479,9 @@ static void dtest_13(struct diag_l0_device *dl0d) { fprintf(stderr, "tty_write error\n"); break; } - diag_tty_iflush(dev->tty_int); //purge echo(s) - if ((10*i/iters) != pc) { - pc +=1; + diag_tty_iflush(dev->tty_int); // purge echo(s) + if ((10 * i / iters) != pc) { + pc += 1; fprintf(stderr, "."); } } @@ -507,13 +523,14 @@ dt_new(struct diag_l0_device *dl0d) { dev->dumbopts.next = NULL; printf("*** Warning ! The DUMBT driver is only for electrical ***\n" - "*** testing ! Do NOT use while connected to a vehicle! ***\n" - "*** refer to doc/scantool-manual.html ***\n"); + "*** testing ! Do NOT use while connected to a vehicle! ***\n" + "*** refer to doc/scantool-manual.html ***\n"); return 0; } -static void dt_del(struct diag_l0_device *dl0d) { +static void +dt_del(struct diag_l0_device *dl0d) { struct dt_device *dev; assert(dl0d); @@ -529,7 +546,8 @@ static void dt_del(struct diag_l0_device *dl0d) { return; } -static struct cfgi *dt_getcfg(struct diag_l0_device *dl0d) { +static struct cfgi * +dt_getcfg(struct diag_l0_device *dl0d) { struct dt_device *dev; if (dl0d == NULL) { return diag_pseterr(DIAG_ERR_BADCFG); @@ -539,12 +557,12 @@ static struct cfgi *dt_getcfg(struct diag_l0_device *dl0d) { return &dev->port; } - /* * Open the diagnostic device, returns a file descriptor * records original state of term interface so we can restore later */ -static int dt_open(struct diag_l0_device *dl0d, int testnum) { +static int +dt_open(struct diag_l0_device *dl0d, int testnum) { struct dt_device *dev; struct diag_serial_settings pset; int dumbopts; @@ -552,12 +570,12 @@ static int dt_open(struct diag_l0_device *dl0d, int testnum) { assert(dl0d); dev = dl0d->l0_int; - if (diag_l0_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "open port %s test # %d\n", - FL, dev->port.val.str, testnum); + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "open port %s test # %d\n", FL, dev->port.val.str, + testnum); } - dt_init(); //make sure it is initted + dt_init(); // make sure it is initted /* try to open TTY */ dev->tty_int = diag_tty_open(dev->port.val.str); @@ -565,7 +583,7 @@ static int dt_open(struct diag_l0_device *dl0d, int testnum) { return diag_iseterr(DIAG_ERR_GENERAL); } - dev->protocol = DIAG_L1_RAW; //cheat ! + dev->protocol = DIAG_L1_RAW; // cheat ! switch (testnum) { case 10: @@ -575,7 +593,7 @@ static int dt_open(struct diag_l0_device *dl0d, int testnum) { pset.speed = 360; break; default: - pset.speed=10400; + pset.speed = 10400; } pset.databits = diag_databits_8; @@ -598,16 +616,16 @@ static int dt_open(struct diag_l0_device *dl0d, int testnum) { dev->fast_break = dumbopts & FAST_BREAK; dev->blockduplex = dumbopts & BLOCKDUPLEX; - //set initial DTR and RTS lines before starting tests; + // set initial DTR and RTS lines before starting tests; if (diag_tty_control(dev->tty_int, !(dev->clr_dtr), dev->set_rts) < 0) { diag_tty_close(dev->tty_int); return diag_iseterr(DIAG_ERR_GENERAL); } - (void)diag_tty_iflush(dev->tty_int); /* Flush unread input */ + (void)diag_tty_iflush(dev->tty_int); /* Flush unread input */ - //printf("Press to stop the test.\n"); - //Currently these run for a fixed time... + // printf("Press to stop the test.\n"); + // Currently these run for a fixed time... switch (testnum) { case 1: dtest_1(dl0d); @@ -637,7 +655,7 @@ static int dt_open(struct diag_l0_device *dl0d, int testnum) { dtest_9(dl0d); break; case 10: - dtest_2(dl0d); //same test, different speed + dtest_2(dl0d); // same test, different speed break; case 11: dtest_11(dl0d); @@ -649,7 +667,7 @@ static int dt_open(struct diag_l0_device *dl0d, int testnum) { dtest_13(dl0d); break; case 14: - dtest_7(dl0d); //same test, different speed + dtest_7(dl0d); // same test, different speed break; default: break; @@ -661,13 +679,11 @@ static int dt_open(struct diag_l0_device *dl0d, int testnum) { return DIAG_ERR_GENERAL; } - static void dt_close(UNUSED(struct diag_l0_device *dl0d)) { return; } - /* * Send a load of data * this is "blocking", i.e. returns only when it's finished or it failed. @@ -676,9 +692,8 @@ dt_close(UNUSED(struct diag_l0_device *dl0d)) { */ static int -dt_send(struct diag_l0_device *dl0d, -UNUSED(const char *subinterface), -const void *data, size_t len) { +dt_send(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), const void *data, + size_t len) { struct dt_device *dev = dl0d->l0_int; /* @@ -690,22 +705,22 @@ const void *data, size_t len) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l0_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "dt_send dl0d=%p , len=%ld. ", - FL, (void *)dl0d, (long)len); - if (diag_l0_debug & DIAG_DEBUG_DATA) { + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "dt_send dl0d=%p , len=%ld. ", FL, (void *)dl0d, + (long)len); + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { diag_data_dump(stderr, data, len); } fprintf(stderr, "\n"); } - if (diag_tty_write(dev->tty_int, data, len) != (int) len) { + if (diag_tty_write(dev->tty_int, data, len) != (int)len) { fprintf(stderr, FLFMT "dt_send: write error\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } - if ( (diag_l0_debug & (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA)) == - (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA) ) { + if ((diag_l0_debug_load() & (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) == + (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) { fprintf(stderr, "\n"); } @@ -716,11 +731,9 @@ const void *data, size_t len) { */ static int -dt_recv(struct diag_l0_device *dl0d, -UNUSED(const char *subinterface), -UNUSED(void *data), size_t len, unsigned int timeout) { - fprintf(stderr, - FLFMT "link %p recv upto %ld bytes timeout %u; doing nothing.\n", +dt_recv(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), UNUSED(void *data), + size_t len, unsigned int timeout) { + fprintf(stderr, FLFMT "link %p recv upto %ld bytes timeout %u; doing nothing.\n", FL, (void *)dl0d, (long)len, timeout); return diag_iseterr(DIAG_ERR_TIMEOUT); @@ -730,8 +743,7 @@ UNUSED(void *data), size_t len, unsigned int timeout) { * Set speed/parity etc */ static int -dt_setspeed(struct diag_l0_device *dl0d, -const struct diag_serial_settings *pset) { +dt_setspeed(struct diag_l0_device *dl0d, const struct diag_serial_settings *pset) { struct dt_device *dev; dev = (struct dt_device *)(dl0d->l0_int); @@ -741,22 +753,22 @@ const struct diag_serial_settings *pset) { return diag_tty_setup(dev->tty_int, &dev->serial); } - static uint32_t dt_getflags(UNUSED(struct diag_l0_device *dl0d)) { return DIAG_L1_HALFDUPLEX; } -static int dt_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { +static int +dt_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { int rv = 0; switch (cmd) { case DIAG_IOCTL_IFLUSH: - //do nothing + // do nothing rv = 0; break; case DIAG_IOCTL_SETSPEED: - rv = dt_setspeed(dl0d, (const struct diag_serial_settings *) data); + rv = dt_setspeed(dl0d, (const struct diag_serial_settings *)data); break; default: rv = DIAG_ERR_IOCTL_NOTSUPP; @@ -766,19 +778,16 @@ static int dt_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { return rv; } - -const struct diag_l0 diag_l0_dumbtest = { - "Dumb interface test suite", - "DUMBT", - -1, //support "all" L1 protos... - dt_init, - dt_new, - dt_getcfg, - dt_del, - dt_open, - dt_close, - dt_getflags, - dt_recv, - dt_send, - dt_ioctl -}; +const struct diag_l0 diag_l0_dumbtest = {"Dumb interface test suite", + "DUMBT", + -1, // support "all" L1 protos... + dt_init, + dt_new, + dt_getcfg, + dt_del, + dt_open, + dt_close, + dt_getflags, + dt_recv, + dt_send, + dt_ioctl}; diff --git a/scantool/diag_l0_elm.c b/scantool/diag_l0_elm.c index 6f045556..3d23c74a 100644 --- a/scantool/diag_l0_elm.c +++ b/scantool/diag_l0_elm.c @@ -42,69 +42,74 @@ #include "diag_l0.h" #include "diag_l1.h" - -#define ELM_BUFSIZE 1000 //fit even max-length iso14230 frames, at 3 ASCII chars per byte. -#define ELM_SLOWNESS 100 //Add this many ms to read timeouts, because ELMs are sloooow -#define ELM_PURGETIME 400 //Time to wait (ms) for a response to "ATI" command +#define ELM_BUFSIZE 1000 // fit even max-length iso14230 frames, at 3 ASCII chars per byte. +#define ELM_SLOWNESS 100 // Add this many ms to read timeouts, because ELMs are sloooow +#define ELM_PURGETIME 400 // Time to wait (ms) for a response to "ATI" command struct elm_device { - int protocol; //current L1 protocol + int protocol; // current L1 protocol - int elmflags; //see defines below + int elmflags; // see defines below - struct cfgi port; - struct cfgi speed; //Host <-> ELM comms + struct cfgi port; + struct cfgi speed; // Host <-> ELM comms struct diag_serial_settings serial; - ttyp *tty_int; /** handle for tty stuff */ + ttyp *tty_int; /** handle for tty stuff */ - uint8_t kb1, kb2; // key bytes from 5 baud init - uint8_t atsh[3]; // current header setting for ISO9141 - struct diag_msg *wm; // custom wakeup message, if set + uint8_t kb1, kb2; // key bytes from 5 baud init + uint8_t atsh[3]; // current header setting for ISO9141 + struct diag_msg *wm; // custom wakeup message, if set }; #define CFGSPEED_DESCR "Host <-> ELM comm speed (bps)" #define CFGSPEED_SHORTN "elmspeed" - -//flags for elmflags; set either 323_BASIC or 327_BASIC but not both; +// flags for elmflags; set either 323_BASIC or 327_BASIC but not both; // _CLONE can be set in addition to the basic type -#define ELM_323_BASIC 1 //device type is 323 -#define ELM_327_BASIC 2 //device type is 327 -#define ELM_32x_CLONE 4 //device is a clone; some commands will not be supported -#define ELM_INITDONE 0x10 //set when "BUS INIT" has happened. This is important for clones. - +#define ELM_323_BASIC 1 // device type is 323 +#define ELM_327_BASIC 2 // device type is 327 +#define ELM_32x_CLONE 4 // device is a clone; some commands will not be supported +#define ELM_INITDONE \ + 0x10 // set when "BUS INIT" has happened. This is important for + // clones. // possible error messages returned by the ELM IC -static const char *elm323_errors[] = {"BUS BUSY", "FB ERROR", "DATA ERROR", "port; } -void elm_del(struct diag_l0_device *dl0d) { +void +elm_del(struct diag_l0_device *dl0d) { struct elm_device *dev; assert(dl0d); @@ -190,86 +198,89 @@ void elm_del(struct diag_l0_device *dl0d) { return; } - static void elm_close(struct diag_l0_device *dl0d) { - uint8_t buf[]="ATPC\x0D"; + uint8_t buf[] = "ATPC\x0D"; struct elm_device *dev; assert(dl0d != NULL); if (dl0d->opened) { - elm_sendcmd(dl0d, buf, 5, 500, NULL); //close protocol. So clean ! + elm_sendcmd(dl0d, buf, 5, 500, NULL); // close protocol. So clean ! } - dev = (struct elm_device *)dl0d->l0_int; + dev = (struct elm_device *)dl0d->l0_int; /* If debugging, print to stderr */ - if (diag_l0_debug & DIAG_DEBUG_CLOSE) { - fprintf(stderr, FLFMT "link %p closing\n", FL, (void *)dl0d); - } + if (diag_l0_debug_load() & DIAG_DEBUG_CLOSE) { + fprintf(stderr, FLFMT "link %p closing\n", FL, (void *)dl0d); + } - diag_tty_close(dev->tty_int); - dev->tty_int = NULL; - dl0d->opened = 0; + diag_tty_close(dev->tty_int); + dev->tty_int = NULL; + dl0d->opened = 0; - return; + return; } - -//elm_parse_errors : look for known error messages in the reply. +// elm_parse_errors : look for known error messages in the reply. // return any match or NULL if nothing found. // data[] must be \0-terminated ! -static const char *elm_parse_errors(struct diag_l0_device *dl0d, uint8_t *data) { +static const char * +elm_parse_errors(struct diag_l0_device *dl0d, uint8_t *data) { struct elm_device *dev; - const char **elm_errors; //just used to select between the 2 error lists + const char **elm_errors; // just used to select between the 2 error lists int i; - dev = (struct elm_device *) dl0d->l0_int; + dev = (struct elm_device *)dl0d->l0_int; - //pick the right set of error messages. Although we could just systematically - //use the vaster ELM327 set of error messages... + // pick the right set of error messages. Although we could just systematically + // use the vaster ELM327 set of error messages... if (dev->elmflags & ELM_323_BASIC) { - elm_errors=elm323_errors; + elm_errors = elm323_errors; } else { elm_errors = elm327_errors; } - for (i=0; elm_errors[i]; i++) { + for (i = 0; elm_errors[i]; i++) { if (strstr((char *)data, elm_errors[i])) { - //we found an error msg, return it. - return elm_errors[i]; + // we found an error msg, return it. + return elm_errors[i]; } } return NULL; } -//Send a command to ELM device and make sure no error occured. Data is passed on directly as a string; -//caller must make sure the string is \r-terminated , i.e. 0x0D-terminated. -//Sending 0A after 0D will cause ELM to interrupt what it's doing to "process" 0A, resulting in a -//failure. -//This func should not be used for commands that elicit a data response (i.e. all data destined to the OBD bus, -//hence not prefixed by "AT"). Response is dumped in *resp (0-terminated) for optional analysis by caller; *resp must be ELM_BUFSIZE long. -//returns 0 if (prompt_good) && ("OK" found anywhere in the response) && (no known error message was present) || -// (prompt_good && ATZ or ATKW command was sent) , since response doesn't contain "OK" for ATZ or ATKW. -//elm_sendcmd should not be called from outside diag_l0_elm.c. +// Send a command to ELM device and make sure no error occured. Data is passed on directly +// as a string; caller must make sure the string is \r-terminated , i.e. 0x0D-terminated. +// Sending 0A after 0D will cause ELM to interrupt what it's doing to "process" 0A, +// resulting in a failure. This func should not be used for commands that elicit a data +// response (i.e. all data destined to the OBD bus, hence not prefixed by "AT"). Response +// is dumped in *resp (0-terminated) for optional analysis by caller; *resp must be +// ELM_BUFSIZE long. returns 0 if (prompt_good) && ("OK" found anywhere in the response) && +// (no known +// error message was present) || (prompt_good && ATZ or ATKW command was +// sent) , since response doesn't contain "OK" for ATZ or ATKW. elm_sendcmd should not be +// called from outside diag_l0_elm.c. static int -elm_sendcmd(struct diag_l0_device *dl0d, const uint8_t *data, size_t len, unsigned int timeout, uint8_t *resp) { - //note : we better not request (len == (size_t) -1) bytes ! The casts between ssize_t and size_t are +elm_sendcmd(struct diag_l0_device *dl0d, const uint8_t *data, size_t len, + unsigned int timeout, uint8_t *resp) { + // note : we better not request (len == (size_t) -1) bytes ! The casts between + // ssize_t and size_t are // "muddy" in here - //ssize_t xferd; + // ssize_t xferd; int rv; - uint8_t ebuf[ELM_BUFSIZE]; //local buffer if caller provides none. + uint8_t ebuf[ELM_BUFSIZE]; // local buffer if caller provides none. uint8_t *buf; struct elm_device *dev; - const char *err_str; //hold a possible error message + const char *err_str; // hold a possible error message dev = (struct elm_device *)dl0d->l0_int; - //we need access to elm_device to access .elmflags + // we need access to elm_device to access .elmflags if (resp == NULL) { - buf=ebuf; //use local buffer + buf = ebuf; // use local buffer } else { buf = resp; // or caller-provided buffer } @@ -281,63 +292,70 @@ elm_sendcmd(struct diag_l0_device *dl0d, const uint8_t *data, size_t len, unsign return diag_iseterr(DIAG_ERR_BADFD); } - if (data[len-1] != 0x0D) { - //Last byte is not a carriage return, this would die. - fprintf(stderr, FLFMT "elm_sendcmd: non-terminated command : %.*s\n", FL, (int) len, (char *) data); - //the %.*s is pure magic : limits the string length to len, even if the string is not null-terminated. + if (data[len - 1] != 0x0D) { + // Last byte is not a carriage return, this would die. + fprintf(stderr, FLFMT "elm_sendcmd: non-terminated command : %.*s\n", FL, + (int)len, (char *)data); + // the %.*s is pure magic : limits the string length to len, even if the + // string is not null-terminated. return diag_iseterr(DIAG_ERR_GENERAL); } - diag_tty_iflush(dev->tty_int); //currently the code often "forgets" data in the input buffer, especially if the previous - //transaction failed. Flushing the input increases the odds of not crashing soon + diag_tty_iflush(dev->tty_int); // currently the code often "forgets" data in the + // input buffer, especially if the previous + // transaction failed. Flushing the input increases + // the odds of not crashing soon - if (diag_l0_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "elm_sendcmd: %.*s\n", FL, (int) len-1, (char *)data); + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "elm_sendcmd: %.*s\n", FL, (int)len - 1, + (char *)data); } rv = diag_tty_write(dev->tty_int, data, len); - if (rv != (int) len) { //XXX danger ! evil cast + if (rv != (int)len) { // XXX danger ! evil cast fprintf(stderr, FLFMT "elm_sendcmd: write error\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } - //next, receive ELM response, within {ms} delay. + // next, receive ELM response, within {ms} delay. - rv=diag_tty_read(dev->tty_int, buf, ELM_BUFSIZE-1, timeout); //rv=# bytes read + rv = diag_tty_read(dev->tty_int, buf, ELM_BUFSIZE - 1, timeout); // rv=# bytes read - if (rv<1) { - //no data or error - if (diag_l0_debug & DIAG_DEBUG_WRITE) { + if (rv < 1) { + // no data or error + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { fprintf(stderr, FLFMT "ELM did not respond\n", FL); } return diag_iseterr(DIAG_ERR_GENERAL); } - if (diag_l0_debug & DIAG_DEBUG_READ) { - elm_parse_cr(buf, rv); //debug output is prettier with this - fprintf(stderr, FLFMT "received %d bytes (%.*s\n); hex: ", FL, rv, rv, (char *)buf); - if (diag_l0_debug & DIAG_DEBUG_DATA) { + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { + elm_parse_cr(buf, rv); // debug output is prettier with this + fprintf(stderr, FLFMT "received %d bytes (%.*s\n); hex: ", FL, rv, rv, + (char *)buf); + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { diag_data_dump(stderr, buf, rv); fprintf(stderr, "\n"); } } - buf[rv]=0; //terminate string - if (buf[rv-1] != '>') { - //if last character isn't the input prompt, there is a problem - fprintf(stderr, FLFMT "ELM not ready (no prompt received): %s\nhex: ", FL, buf); + buf[rv] = 0; // terminate string + if (buf[rv - 1] != '>') { + // if last character isn't the input prompt, there is a problem + fprintf(stderr, FLFMT "ELM not ready (no prompt received): %s\nhex: ", FL, + buf); diag_data_dump(stderr, buf, rv); fprintf(stderr, "\n"); return diag_iseterr(DIAG_ERR_GENERAL); } - //At this point we got a prompt but there may have been an error message. - //There is some ambiguity in the ELM datasheets on the exact format of the replies. - //1) the prompt character '>' is always alone on its line; - //2) depending on some parameters, it may be preceded by 0D or 0D 0A - //3) some errors ( "' is always alone on its line; 2) depending + // on some parameters, it may be preceded by 0D or 0D 0A 3) some errors ( "", bad reply :"NO DATA\r>" - //let's just use strstr() to find occurences for each known error. - //it'll take a while but speed isn't normally critical when sending commands + // ex. of good reply : "41 00 00 \r>", bad reply :"NO DATA\r>" + // let's just use strstr() to find occurences for each known error. + // it'll take a while but speed isn't normally critical when sending commands err_str = elm_parse_errors(dl0d, buf); @@ -346,11 +364,11 @@ elm_sendcmd(struct diag_l0_device *dl0d, const uint8_t *data, size_t len, unsign return diag_iseterr(DIAG_ERR_GENERAL); } - //check if we either 1)got a positive response "OK" - //2)were sending ATZ (special case hack, it doesn't answer "OK") + // check if we either 1)got a positive response "OK" + // 2)were sending ATZ (special case hack, it doesn't answer "OK") if ((strstr((char *)buf, "OK") != NULL) || - (strstr((char *)data, "ATKW") != NULL) || - (strstr((char *)data, "ATZ") != NULL)) { + (strstr((char *)data, "ATKW") != NULL) || + (strstr((char *)data, "ATZ") != NULL)) { return 0; } @@ -358,7 +376,6 @@ elm_sendcmd(struct diag_l0_device *dl0d, const uint8_t *data, size_t len, unsign diag_data_dump(stderr, buf, rv); fprintf(stderr, "\n"); return diag_iseterr(DIAG_ERR_GENERAL); - } /* * Open the diagnostic device @@ -366,29 +383,32 @@ elm_sendcmd(struct diag_l0_device *dl0d, const uint8_t *data, size_t len, unsign */ static int elm_open(struct diag_l0_device *dl0d, int iProtocol) { - int i,rv; + int i, rv; struct elm_device *dev; struct diag_serial_settings sset; const uint8_t *buf; uint8_t rxbuf[ELM_BUFSIZE]; const char **elm_official; - const char **elm_clones; //point to elm323_ or elm327_ clone and official version string lists + const char **elm_clones; // point to elm323_ or elm327_ clone and official version + // string lists assert(dl0d); dev = dl0d->l0_int; - if (diag_l0_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "open port %s L1proto %d\n", - FL, dev->port.val.str, iProtocol); + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "open port %s L1proto %d\n", FL, dev->port.val.str, + iProtocol); } elm_init(); - //sending ATZ to elm will wipe out current header setting - dev->atsh[0]=0; dev->atsh[1]=0; dev->atsh[2]=0; + // sending ATZ to elm will wipe out current header setting + dev->atsh[0] = 0; + dev->atsh[1] = 0; + dev->atsh[2] = 0; - //throw away previous wakeup message setting, if any + // throw away previous wakeup message setting, if any if (dev->wm != NULL) { diag_freemsg(dev->wm); } @@ -401,157 +421,165 @@ elm_open(struct diag_l0_device *dl0d, int iProtocol) { } dev->protocol = iProtocol; - //try sending a command to elm327 at each possible speed until we get a response + // try sending a command to elm327 at each possible speed until we get a response sset.databits = diag_databits_8; sset.stopbits = diag_stopbits_1; sset.parflag = diag_par_n; - for (i=0; elm_speeds[i]; i++) { + for (i = 0; elm_speeds[i]; i++) { sset.speed = elm_speeds[i]; // skip if custom speed was already tried: - if (sset.speed == (unsigned) dev->speed.val.i) { + if (sset.speed == (unsigned)dev->speed.val.i) { continue; } if (sset.speed == ELM_CUSTOMSPEED) { - //magic flag to retrieve custom speed - sset.speed = (unsigned) dev->speed.val.i; + // magic flag to retrieve custom speed + sset.speed = (unsigned)dev->speed.val.i; } fprintf(stderr, FLFMT "Sending ATI to ELM32x at %u...\n", FL, sset.speed); dev->serial = sset; - if ((rv=diag_tty_setup(dev->tty_int, &sset))) { - fprintf(stderr, FLFMT "Error setting %u;8N1 on %s\n", - FL, sset.speed, dev->port.val.str); + if ((rv = diag_tty_setup(dev->tty_int, &sset))) { + fprintf(stderr, FLFMT "Error setting %u;8N1 on %s\n", FL, + sset.speed, dev->port.val.str); elm_close(dl0d); return diag_iseterr(rv); } - diag_tty_iflush(dev->tty_int); /* Flush unread input */ + diag_tty_iflush(dev->tty_int); /* Flush unread input */ - //At this stage, the ELM has possibly been powered up for a while; - //it may have an unfinished command / garbage in its input buffer. We - //need to clear that before sending the real ATZ ==> ATI is quick and safe; elm_purge does this. + // At this stage, the ELM has possibly been powered up for a while; + // it may have an unfinished command / garbage in its input buffer. We + // need to clear that before sending the real ATZ ==> ATI is quick and + // safe; elm_purge does this. - dev->elmflags=0; //we know nothing yet + dev->elmflags = 0; // we know nothing yet - rv=elm_purge(dl0d); - //if rv=0, we got a prompt so we know speed is set properly. + rv = elm_purge(dl0d); + // if rv=0, we got a prompt so we know speed is set properly. if (rv == 0) { break; } } - if (elm_speeds[i]==0) { - fprintf(stderr, FLFMT "No response from ELM323/ELM327. Verify connection to ELM\n", FL); + if (elm_speeds[i] == 0) { + fprintf(stderr, + FLFMT "No response from ELM323/ELM327. Verify connection to ELM\n", + FL); elm_close(dl0d); return diag_iseterr(DIAG_ERR_BADIFADAPTER); } - if (diag_l0_debug&DIAG_DEBUG_OPEN) { + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "elm_open : sending ATZ...\n", FL); } - //the command "ATZ" causes a full reset and the ELM replies with - //a string like "ELM32x vX.Xx\n>" + // the command "ATZ" causes a full reset and the ELM replies with + // a string like "ELM32x vX.Xx\n>" - buf=(uint8_t *)"ATZ\x0D"; - rv=elm_sendcmd(dl0d, buf, 4, 2000, rxbuf); + buf = (uint8_t *)"ATZ\x0D"; + rv = elm_sendcmd(dl0d, buf, 4, 2000, rxbuf); if (rv) { fprintf(stderr, FLFMT "elm_open : ATZ failed !\n", FL); elm_close(dl0d); return diag_iseterr(DIAG_ERR_BADIFADAPTER); } - //Correct prompt received; try to identify device. + // Correct prompt received; try to identify device. // 1) guess 323 vs 327 - if (strstr((char *)rxbuf, "ELM323")!=NULL) { + if (strstr((char *)rxbuf, "ELM323") != NULL) { dev->elmflags |= ELM_323_BASIC; - elm_official=elm323_official; - elm_clones=elm323_clones; - } else if (strstr((char *)rxbuf, "ELM327")!=NULL) { + elm_official = elm323_official; + elm_clones = elm323_clones; + } else if (strstr((char *)rxbuf, "ELM327") != NULL) { dev->elmflags |= ELM_327_BASIC; - elm_official=elm327_official; - elm_clones=elm327_clones; + elm_official = elm327_official; + elm_clones = elm327_clones; } else { - fprintf(stderr, FLFMT "no valid version string !! Report this !. Got:\n%s\n", FL, rxbuf); - //no point in continuing... + fprintf(stderr, + FLFMT "no valid version string !! Report this !. Got:\n%s\n", FL, + rxbuf); + // no point in continuing... elm_close(dl0d); return diag_iseterr(DIAG_ERR_BADIFADAPTER); } // 2) identify valid VS clone devices. - rv=0; // temp "device identified" flag - for (i=0; elm_clones[i]; i++) { + rv = 0; // temp "device identified" flag + for (i = 0; elm_clones[i]; i++) { if (strstr((char *)rxbuf, elm_clones[i])) { - printf("Clone ELM found, v%s. Expect inferior performance\n", elm_clones[i]); + printf("Clone ELM found, v%s. Expect inferior performance\n", + elm_clones[i]); dev->elmflags |= ELM_32x_CLONE; - rv=1; + rv = 1; break; } } - if (rv==0) { - for (i=0; elm_official[i]; i++) { - if (strstr((char *)rxbuf, elm_official[i])) { + if (rv == 0) { + for (i = 0; elm_official[i]; i++) { + if (strstr((char *)rxbuf, elm_official[i])) { printf("Official ELM found, v%s\n", elm_official[i]); - rv=1; + rv = 1; break; } } } - if (rv==0) { - //still not identified : assume clone. + if (rv == 0) { + // still not identified : assume clone. dev->elmflags |= ELM_32x_CLONE; - printf("ELM version not recognized! Please report this ! Response was:\n%s\n", rxbuf); + printf("ELM version not recognized! Please report this ! Response " + "was:\n%s\n", + rxbuf); } if ((dev->elmflags & ELM_323_BASIC) && (dev->elmflags & ELM_32x_CLONE)) { printf("A 323 clone ? Report this !\n"); } - - if (diag_l0_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "ELM reset success, elmflags=%#x\n", FL, dev->elmflags); + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "ELM reset success, elmflags=%#x\n", FL, + dev->elmflags); } - dl0d->opened = 1; //TODO : use this flag to skip the clone detection next time + dl0d->opened = 1; // TODO : use this flag to skip the clone detection next time - //now send "ATE0\n" command to disable echo. - buf=(uint8_t *)"ATE0\x0D"; + // now send "ATE0\n" command to disable echo. + buf = (uint8_t *)"ATE0\x0D"; if (elm_sendcmd(dl0d, buf, 5, 500, NULL)) { - if (diag_l0_debug & DIAG_DEBUG_OPEN) { + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "sending \"ATE0\" failed\n", FL); } elm_close(dl0d); return diag_iseterr(DIAG_ERR_BADIFADAPTER); } - //ATL0 : disable linefeeds - buf=(uint8_t *)"ATL0\x0D"; + // ATL0 : disable linefeeds + buf = (uint8_t *)"ATL0\x0D"; if (elm_sendcmd(dl0d, buf, 5, 500, NULL)) { - if (diag_l0_debug & DIAG_DEBUG_OPEN) { + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "sending \"ATL0\" failed\n", FL); } elm_close(dl0d); return diag_iseterr(DIAG_ERR_BADIFADAPTER); } - //ATH1 : always show header bytes - buf=(uint8_t *)"ATH1\x0D"; + // ATH1 : always show header bytes + buf = (uint8_t *)"ATH1\x0D"; if (elm_sendcmd(dl0d, buf, 5, 500, NULL)) { - if (diag_l0_debug & DIAG_DEBUG_OPEN) { + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "sending \"ATH1\" failed\n", FL); } elm_close(dl0d); return diag_iseterr(DIAG_ERR_BADIFADAPTER); } - //for elm327 only: disable memory + // for elm327 only: disable memory if (dev->elmflags & ELM_327_BASIC) { - buf=(uint8_t *)"ATM0\x0D"; + buf = (uint8_t *)"ATM0\x0D"; if (elm_sendcmd(dl0d, buf, 5, 500, NULL)) { - if (diag_l0_debug & DIAG_DEBUG_OPEN) { + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "sending \"ATM0\" failed\n", FL); } elm_close(dl0d); @@ -559,67 +587,65 @@ elm_open(struct diag_l0_device *dl0d, int iProtocol) { } } - //check if proto is really supported (323 supports only 9141 and 14230) + // check if proto is really supported (323 supports only 9141 and 14230) if ((dev->elmflags & ELM_323_BASIC) && - ((iProtocol != DIAG_L1_ISO9141) && - (iProtocol != DIAG_L1_ISO14230))) { + ((iProtocol != DIAG_L1_ISO9141) && (iProtocol != DIAG_L1_ISO14230))) { return diag_iseterr(DIAG_ERR_PROTO_NOTSUPP); } - //if 327, set proto when possible; we won't if 14230, because init type (fast vs slow) isn't decided yet + // if 327, set proto when possible; we won't if 14230, because init type (fast vs + // slow) isn't decided yet // CAN is also not implemented here - buf=NULL; + buf = NULL; if (dev->elmflags & ELM_327_BASIC) { switch (iProtocol) { case DIAG_L1_J1850_PWM: - buf=(uint8_t *)"ATTP1\x0D"; + buf = (uint8_t *)"ATTP1\x0D"; break; case DIAG_L1_J1850_VPW: - buf=(uint8_t *)"ATTP2\x0D"; + buf = (uint8_t *)"ATTP2\x0D"; break; case DIAG_L1_ISO9141: - buf=(uint8_t *)"ATTP3\x0D"; + buf = (uint8_t *)"ATTP3\x0D"; break; default: - buf=NULL; + buf = NULL; } } if (buf != NULL) { if (elm_sendcmd(dl0d, buf, 6, 500, NULL)) { - if (diag_l0_debug & DIAG_DEBUG_OPEN) { + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "sending \"ATTPx\" failed\n", FL); } - elm_close(dl0d); - return diag_iseterr(DIAG_ERR_BADIFADAPTER); + elm_close(dl0d); + return diag_iseterr(DIAG_ERR_BADIFADAPTER); } } - - //at this point : ELM is ready for further ops - if (diag_l0_debug & DIAG_DEBUG_OPEN) { + // at this point : ELM is ready for further ops + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "ELM ready.\n", FL); } return 0; } - /* * Fastinit & slowinit: - * ELM should manage slow/fast init automatically... Until the code from levels L1 and up can deal with - * this, the bus will manually be initialized. - * Only callable internally. Not for export !! - * Unsupported by some (all?) clones !! (they handle the init internally, on demand) + * ELM should manage slow/fast init automatically... Until the code from levels L1 and up + * can deal with this, the bus will manually be initialized. Only callable internally. Not + * for export !! Unsupported by some (all?) clones !! (they handle the init internally, on + * demand) */ static int elm_fastinit(struct diag_l0_device *dl0d) { - uint8_t *cmds= (uint8_t *) "ATFI\x0D"; + uint8_t *cmds = (uint8_t *)"ATFI\x0D"; - if (diag_l0_debug & DIAG_DEBUG_PROTO) { + if (diag_l0_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "ELM forced fastinit...\n", FL); } - //send command with 1000ms timeout (guessing) + // send command with 1000ms timeout (guessing) if (elm_sendcmd(dl0d, cmds, 5, 1000, NULL)) { fprintf(stderr, FLFMT "Command ATFI failed\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); @@ -627,35 +653,35 @@ elm_fastinit(struct diag_l0_device *dl0d) { return 0; } - static int elm_slowinit(struct diag_l0_device *dl0d) { - uint8_t *cmds=(uint8_t *)"ATSI\x0D"; + uint8_t *cmds = (uint8_t *)"ATSI\x0D"; - if (diag_l0_debug & DIAG_DEBUG_PROTO) { + if (diag_l0_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "ELM forced slowinit...\n", FL); } - //huge timeout of 2.8s. Not sure if this is adequate + // huge timeout of 2.8s. Not sure if this is adequate if (elm_sendcmd(dl0d, cmds, 5, 2800, NULL)) { fprintf(stderr, FLFMT "Command ATSI failed\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } return 0; - } -//elm_bogusinit : send a 01 00 request to force ELM to init bus. -//Only used to force clones to establish a connection... hack-grade because it assumes all ECUs support this. +// elm_bogusinit : send a 01 00 request to force ELM to init bus. +// Only used to force clones to establish a connection... hack-grade because it assumes all +// ECUs support this. // non-OBD ECUs may not work with this. ELM clones suck... -// TODO : add argument to allow either a 01 00 request (SID1 PID0, J1979) or 3E (iso14230 TesterPresent) request to force init. +// TODO : add argument to allow either a 01 00 request (SID1 PID0, J1979) or 3E (iso14230 +// TesterPresent) request to force init. static int elm_bogusinit(struct diag_l0_device *dl0d, unsigned int timeout) { int rv; struct elm_device *dev; uint8_t buf[MAXRBUF]; - uint8_t generic_data[] = {0x01,0x00}; // J1979 request only - uint8_t iso9141_data[] = {0x68,0x6a,0xf1,0x01,0x00}; // with ISO9141 hdr + uint8_t generic_data[] = {0x01, 0x00}; // J1979 request only + uint8_t iso9141_data[] = {0x68, 0x6a, 0xf1, 0x01, 0x00}; // with ISO9141 hdr const char *err_str; dev = dl0d->l0_int; @@ -669,25 +695,25 @@ elm_bogusinit(struct diag_l0_device *dl0d, unsigned int timeout) { } // receive everything; we're hoping for a prompt at the end and no error message. - rv=diag_tty_read(dev->tty_int, buf, MAXRBUF-5, timeout); //rv=# bytes read - if (diag_l0_debug & (DIAG_DEBUG_WRITE | DIAG_DEBUG_READ)) { + rv = diag_tty_read(dev->tty_int, buf, MAXRBUF - 5, timeout); // rv=# bytes read + if (diag_l0_debug_load() & (DIAG_DEBUG_WRITE | DIAG_DEBUG_READ)) { fprintf(stderr, FLFMT "received %d bytes\n", FL, rv); - if (diag_l0_debug & DIAG_DEBUG_DATA) { + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { elm_parse_cr(buf, rv); fprintf(stderr, FLFMT "(got %.*s)\n", FL, rv, buf); } } - if (rv<1) { - //no data or error - if (diag_l0_debug & DIAG_DEBUG_WRITE) { + if (rv < 1) { + // no data or error + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { fprintf(stderr, FLFMT "ELM did not respond\n", FL); } return diag_iseterr(DIAG_ERR_GENERAL); } - buf[rv]=0; //terminate string - if (buf[rv-1] != '>') { - //if last character isn't the input prompt, there is a problem + buf[rv] = 0; // terminate string + if (buf[rv - 1] != '>') { + // if last character isn't the input prompt, there is a problem fprintf(stderr, FLFMT "ELM not ready (no prompt received): %s\n", FL, buf); return diag_iseterr(DIAG_ERR_GENERAL); } @@ -700,7 +726,6 @@ elm_bogusinit(struct diag_l0_device *dl0d, unsigned int timeout) { } return 0; - } // set wakeup message @@ -710,7 +735,8 @@ elm_updatewm(struct diag_l0_device *dl0d) { uint8_t wm[18]; dev = (struct elm_device *)dl0d->l0_int; - sprintf((char *) wm, "ATWM %02X %02X %02X %02X\x0D", dev->wm->data[0], dev->wm->data[1], dev->wm->data[2], dev->wm->data[3]); + sprintf((char *)wm, "ATWM %02X %02X %02X %02X\x0D", dev->wm->data[0], + dev->wm->data[1], dev->wm->data[2], dev->wm->data[3]); if (elm_sendcmd(dl0d, wm, 17, 500, NULL) < 0) { fprintf(stderr, FLFMT "elm_updatewm: ATWM failed\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); @@ -726,11 +752,11 @@ static int elm_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { const uint8_t *buf; int rv = DIAG_ERR_INIT_NOTSUPP; - unsigned int timeout=0; //for bogus init + unsigned int timeout = 0; // for bogus init struct elm_device *dev; - if (diag_l0_debug & DIAG_DEBUG_WRITE) { + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { fprintf(stderr, FLFMT "ELM initbus type %d\n", FL, in->type); } @@ -741,178 +767,194 @@ elm_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { } if (dev->elmflags & ELM_32x_CLONE) { - printf("Note : explicit bus init not available on clones. Errors here are ignored.\n"); - dev->elmflags &= ~ELM_INITDONE; //clear flag + printf("Note : explicit bus init not available on clones. Errors here are " + "ignored.\n"); + dev->elmflags &= ~ELM_INITDONE; // clear flag } switch (in->type) { - case DIAG_L1_INITBUS_FAST: { - uint8_t fmt, src, tgt; - uint8_t setproto[]="ATTP5\x0D"; - uint8_t sethdr[15]; //format: "ATSH xx yy zz\x0D" - - fmt=(in->physaddr)? 0x81:0xC1; - src=in->testerid; - tgt=in->addr; - if (dev->elmflags & ELM_327_BASIC) { - //only needed for 327s (ATTP not available on ELM323) - //set proto; We assume iso14230 since it's a fast init - rv=elm_sendcmd(dl0d, setproto, 6, 500, NULL); - if (rv < 0) { - break; - } + case DIAG_L1_INITBUS_FAST: { + uint8_t fmt, src, tgt; + uint8_t setproto[] = "ATTP5\x0D"; + uint8_t sethdr[15]; // format: "ATSH xx yy zz\x0D" + + fmt = (in->physaddr) ? 0x81 : 0xC1; + src = in->testerid; + tgt = in->addr; + if (dev->elmflags & ELM_327_BASIC) { + // only needed for 327s (ATTP not available on ELM323) + // set proto; We assume iso14230 since it's a fast init + rv = elm_sendcmd(dl0d, setproto, 6, 500, NULL); + if (rv < 0) { + break; } + } - // set wakeup message if applicable - if (dev->wm != NULL) { - rv=elm_updatewm(dl0d); - if (rv < 0) { - return rv; - } + // set wakeup message if applicable + if (dev->wm != NULL) { + rv = elm_updatewm(dl0d); + if (rv < 0) { + return rv; } + } - sprintf((char *) sethdr, "ATSH %02X %02X %02X\x0D", fmt, tgt, src); - rv=elm_sendcmd(dl0d, sethdr, 14, 500, NULL); - - //explicit init is not supported by clones, they wait for the first OBD request... - if ((dev->elmflags & ELM_32x_CLONE)==0) { - rv = elm_fastinit(dl0d); - if (!rv) { - dev->elmflags |= ELM_INITDONE; - } - } //if explicit init failed we'll try a bogus init anyway - timeout=1500; - } //case fastinit - break; //case fastinit - case DIAG_L1_INITBUS_5BAUD: - //if 327 : set proto first - if (dev->elmflags & ELM_327_BASIC) { - if (dev->protocol & DIAG_L1_ISO9141) { - buf=(uint8_t *) "ATTP3\x0D"; - } else if (dev->protocol & DIAG_L1_ISO14230) { - buf=(uint8_t *) "ATTP4\x0D"; - } else { // illegal combination ! - return diag_iseterr( - DIAG_ERR_INIT_NOTSUPP); - } - - rv=elm_sendcmd(dl0d, buf, 6, 500, NULL); - if (rv < 0) { - break; - } + sprintf((char *)sethdr, "ATSH %02X %02X %02X\x0D", fmt, tgt, src); + rv = elm_sendcmd(dl0d, sethdr, 14, 500, NULL); + + // explicit init is not supported by clones, they wait for the first OBD + // request... + if ((dev->elmflags & ELM_32x_CLONE) == 0) { + rv = elm_fastinit(dl0d); + if (!rv) { + dev->elmflags |= ELM_INITDONE; + } + } // if explicit init failed we'll try a bogus init anyway + timeout = 1500; + } // case fastinit + break; // case fastinit + case DIAG_L1_INITBUS_5BAUD: + // if 327 : set proto first + if (dev->elmflags & ELM_327_BASIC) { + if (dev->protocol & DIAG_L1_ISO9141) { + buf = (uint8_t *)"ATTP3\x0D"; + } else if (dev->protocol & DIAG_L1_ISO14230) { + buf = (uint8_t *)"ATTP4\x0D"; + } else { // illegal combination ! + return diag_iseterr(DIAG_ERR_INIT_NOTSUPP); } - // set wakeup message if applicable - if (dev->wm != NULL) { - rv=elm_updatewm(dl0d); - if (rv < 0) { - return rv; - } + rv = elm_sendcmd(dl0d, buf, 6, 500, NULL); + if (rv < 0) { + break; } + } - //set init address - if ((dev->elmflags & ELM_323_BASIC) && (in->addr != 0x33)) { - fprintf(stderr, FLFMT "elm_initbus: ELM323 doesn't support target address %02X", FL, in->addr); - return diag_iseterr(DIAG_ERR_GENERAL); + // set wakeup message if applicable + if (dev->wm != NULL) { + rv = elm_updatewm(dl0d); + if (rv < 0) { + return rv; } - if (in->addr != 0x33) { - uint8_t iia[15]; - sprintf((char *) iia, "ATIIA %02X\x0D", in->addr); - rv=elm_sendcmd(dl0d, iia, 9, 500, NULL); - if (rv < 0) { - fprintf(stderr, FLFMT "elm_initbus: ATIIA %02X failed\n", FL, in->addr); - return diag_iseterr(DIAG_ERR_GENERAL); - } + } + + // set init address + if ((dev->elmflags & ELM_323_BASIC) && (in->addr != 0x33)) { + fprintf(stderr, + FLFMT + "elm_initbus: ELM323 doesn't support target address %02X", + FL, in->addr); + return diag_iseterr(DIAG_ERR_GENERAL); + } + if (in->addr != 0x33) { + uint8_t iia[15]; + sprintf((char *)iia, "ATIIA %02X\x0D", in->addr); + rv = elm_sendcmd(dl0d, iia, 9, 500, NULL); + if (rv < 0) { + fprintf(stderr, FLFMT "elm_initbus: ATIIA %02X failed\n", + FL, in->addr); + return diag_iseterr(DIAG_ERR_GENERAL); } + } - //accept nonstandard keybytes during init - if (dev->elmflags & ELM_327_BASIC) { - buf=(uint8_t *) "ATKW0\x0D"; - rv=elm_sendcmd(dl0d, buf, 6, 500, NULL); - if (rv < 0) { - fprintf(stderr, - FLFMT - "elm_initbus: ATKW0 failed, " - "continuing anyway\n", - FL); - } + // accept nonstandard keybytes during init + if (dev->elmflags & ELM_327_BASIC) { + buf = (uint8_t *)"ATKW0\x0D"; + rv = elm_sendcmd(dl0d, buf, 6, 500, NULL); + if (rv < 0) { + fprintf(stderr, + FLFMT + "elm_initbus: ATKW0 failed, " + "continuing anyway\n", + FL); } + } - //explicit init is not supported by clones - if ((dev->elmflags & ELM_32x_CLONE)==0) { - rv = elm_slowinit(dl0d); - if (!rv) { - dev->elmflags |= ELM_INITDONE; - } + // explicit init is not supported by clones + if ((dev->elmflags & ELM_32x_CLONE) == 0) { + rv = elm_slowinit(dl0d); + if (!rv) { + dev->elmflags |= ELM_INITDONE; } - timeout=4200; //slow init is slow ! - - //query elm for keybytes - dev->kb1 = 0; dev->kb2 = 0; - if (dev->elmflags & ELM_INITDONE) { - uint8_t rxbuf[ELM_BUFSIZE]; - unsigned int kb1, kb2; - - buf=(uint8_t *) "ATKW\x0D"; - rv=elm_sendcmd(dl0d, buf, 5, 500, rxbuf); - if (rv < 0) { - fprintf(stderr, FLFMT "elm_initbus: ATKW failed, continuing anyway\n", FL); - // TODO: for clones without ATKW, can - // fall back to ATBD. If ATBD response - // starts with 06 addr 55 xx yy aa bb - // and aa=yy^0xff and bb=addr^0xff then - // xx and yy should be key bytes - rv = 0; - } else if (sscanf((char *)rxbuf, "1:%02X 2:%02X", &kb1, &kb2) == 2) { - dev->kb1 = kb1; - dev->kb2 = kb2; - in->kb1 = kb1; - in->kb2 = kb2; - } else { - fprintf(stderr, FLFMT "elm_initbus: ATKW failed, continuing anyway\n", FL); - rv = 0; - } + } + timeout = 4200; // slow init is slow ! + + // query elm for keybytes + dev->kb1 = 0; + dev->kb2 = 0; + if (dev->elmflags & ELM_INITDONE) { + uint8_t rxbuf[ELM_BUFSIZE]; + unsigned int kb1, kb2; + + buf = (uint8_t *)"ATKW\x0D"; + rv = elm_sendcmd(dl0d, buf, 5, 500, rxbuf); + if (rv < 0) { + fprintf(stderr, + FLFMT + "elm_initbus: ATKW failed, continuing anyway\n", + FL); + // TODO: for clones without ATKW, can + // fall back to ATBD. If ATBD response + // starts with 06 addr 55 xx yy aa bb + // and aa=yy^0xff and bb=addr^0xff then + // xx and yy should be key bytes + rv = 0; + } else if (sscanf((char *)rxbuf, "1:%02X 2:%02X", &kb1, &kb2) == + 2) { + dev->kb1 = kb1; + dev->kb2 = kb2; + in->kb1 = kb1; + in->kb2 = kb2; + } else { + fprintf(stderr, + FLFMT + "elm_initbus: ATKW failed, continuing anyway\n", + FL); + rv = 0; } + } - // enable receipt of >7 byte messages, if possible - if (dev->elmflags & ELM_INITDONE) { - buf=(uint8_t *) "ATAL\x0D"; - rv=elm_sendcmd(dl0d, buf, 5, 500, NULL); - if (rv < 0) { - fprintf(stderr, FLFMT "elm_initbus: ATAL failed, continuing anyway\n", FL); - rv = 0; - } + // enable receipt of >7 byte messages, if possible + if (dev->elmflags & ELM_INITDONE) { + buf = (uint8_t *)"ATAL\x0D"; + rv = elm_sendcmd(dl0d, buf, 5, 500, NULL); + if (rv < 0) { + fprintf(stderr, + FLFMT + "elm_initbus: ATAL failed, continuing anyway\n", + FL); + rv = 0; } + } - break; - default: - rv = DIAG_ERR_INIT_NOTSUPP; - break; + break; + default: + rv = DIAG_ERR_INIT_NOTSUPP; + break; } - if ((dev->elmflags & ELM_INITDONE)==0) { - // init not done, either because it's a clone (explicit init unsupported), or another reason. - // two choices : A) assume comms will be OBD compliant, so request "01 00" has to be supported - // B) tweak _recv() to skip the "BUS INIT: " line that ELM will send at the next request. - // A is easier for now... - // Note that since we don't check for "DIAG_ERR_INIT_NOTSUPP" here, we allow the ELM to (possibly) - // carry out an incorrect init. I can't see when this can be a problem. - // Note : clones suck - rv=elm_bogusinit(dl0d, timeout); + if ((dev->elmflags & ELM_INITDONE) == 0) { + // init not done, either because it's a clone (explicit init unsupported), + // or another reason. two choices : A) assume comms will be OBD compliant, + // so request "01 00" has to be supported B) tweak _recv() to skip the "BUS + // INIT: " line that ELM will send at the next request. A is easier for + // now... Note that since we don't check for "DIAG_ERR_INIT_NOTSUPP" here, + // we allow the ELM to (possibly) carry out an incorrect init. I can't see + // when this can be a problem. Note : clones suck + rv = elm_bogusinit(dl0d, timeout); if (rv == 0) { dev->elmflags |= ELM_INITDONE; } } - return rv? diag_iseterr(rv):0; - + return rv ? diag_iseterr(rv) : 0; } -//elm_purge : sends ATI command and checks for a valid prompt. This is faster than ATZ. -//use : if the ELM received garbage before ATI, ex.: "\xFF\xFFATI\r" it will just reject -//the invalid command but still give a valid prompt. -//Return 0 only if a valid prompt was received. -static int elm_purge(struct diag_l0_device *dl0d) { +// elm_purge : sends ATI command and checks for a valid prompt. This is faster than ATZ. +// use : if the ELM received garbage before ATI, ex.: "\xFF\xFFATI\r" it will just reject +// the invalid command but still give a valid prompt. +// Return 0 only if a valid prompt was received. +static int +elm_purge(struct diag_l0_device *dl0d) { uint8_t buf[ELM_BUFSIZE] = "ATI\x0D"; int rv; struct elm_device *dev = dl0d->l0_int; @@ -926,8 +968,8 @@ static int elm_purge(struct diag_l0_device *dl0d) { return DIAG_ERR_GENERAL; } - if (buf[rv-1] != '>') { - if (diag_l0_debug & DIAG_DEBUG_DATA) { + if (buf[rv - 1] != '>') { + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { fprintf(stderr, FLFMT "elm_purge: got ", FL); diag_data_dump(stderr, buf, rv); fprintf(stderr, "\n"); @@ -941,17 +983,16 @@ static int elm_purge(struct diag_l0_device *dl0d) { * Send a load of data * * Directly send hex-ASCII; exit without receiving response. - * Upper levels don't append 0x0D / 0x0A at the end, we take care of adding the required 0x0D. - * "AT"* commands sould not be sent with this function. - * Returns 0 on success + * Upper levels don't append 0x0D / 0x0A at the end, we take care of adding the required + * 0x0D. "AT"* commands sould not be sent with this function. Returns 0 on success */ static int -elm_send(struct diag_l0_device *dl0d, - UNUSED(const char *subinterface), const void *data, size_t len) { +elm_send(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), const void *data, + size_t len) { uint8_t buf[ELM_BUFSIZE]; struct elm_device *dev = dl0d->l0_int; - //ssize_t xferd; + // ssize_t xferd; int rv; unsigned int i; @@ -963,14 +1004,16 @@ elm_send(struct diag_l0_device *dl0d, return diag_iseterr(DIAG_ERR_BADLEN); } - if ((2*len)>(ELM_BUFSIZE-1)) { - //too much data for buffer size - fprintf(stderr, FLFMT "ELM: too much data for buffer (report this bug please!)\n", FL); + if ((2 * len) > (ELM_BUFSIZE - 1)) { + // too much data for buffer size + fprintf(stderr, + FLFMT "ELM: too much data for buffer (report this bug please!)\n", + FL); return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l0_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "ELM: sending %d bytes\n", FL, (int) len); + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "ELM: sending %d bytes\n", FL, (int)len); } if ((dev->protocol & DIAG_L1_ISO9141) && memcmp(dev->atsh, data, 3)) { @@ -978,23 +1021,23 @@ elm_send(struct diag_l0_device *dl0d, (unsigned int)((uint8_t *)data)[0], (unsigned int)((uint8_t *)data)[1], (unsigned int)((uint8_t *)data)[2]); - rv=elm_sendcmd(dl0d, buf, 14, 500, NULL); + rv = elm_sendcmd(dl0d, buf, 14, 500, NULL); if (rv < 0) { - fprintf(stderr, FLFMT "elm_send: ATSH failed\n",FL); + fprintf(stderr, FLFMT "elm_send: ATSH failed\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } // if ISO9141 protocol setting with KWP message format, // adjust receive filter if ((dev->atsh[0] & 0x80) && - (dev->atsh[2] == (unsigned int)((uint8_t *)data)[2])) { + (dev->atsh[2] == (unsigned int)((uint8_t *)data)[2])) { // already sent ATSR for this address } else if ((unsigned int)((uint8_t *)data)[0] & 0x80) { sprintf((char *)buf, "ATSR %02X\x0D", (unsigned int)((uint8_t *)data)[2]); - rv=elm_sendcmd(dl0d, buf, 8, 500, NULL); + rv = elm_sendcmd(dl0d, buf, 8, 500, NULL); if (rv < 0) { - fprintf(stderr, FLFMT "elm_send: ATSR failed\n",FL); + fprintf(stderr, FLFMT "elm_send: ATSR failed\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } } @@ -1002,26 +1045,27 @@ elm_send(struct diag_l0_device *dl0d, memcpy(dev->atsh, data, 3); } - for (i=0; iprotocol & DIAG_L1_ISO9141) { i -= 6; - rv=diag_tty_write(dev->tty_int, buf+6, i+1); // skip header + rv = diag_tty_write(dev->tty_int, buf + 6, i + 1); // skip header } else { - rv=diag_tty_write(dev->tty_int, buf, i+1); + rv = diag_tty_write(dev->tty_int, buf, i + 1); } - if (rv != (int) (i+1)) { //XXX danger ! evil cast ! - fprintf(stderr, FLFMT "elm_send:write error\n",FL); + if (rv != (int)(i + 1)) { // XXX danger ! evil cast ! + fprintf(stderr, FLFMT "elm_send:write error\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } return 0; @@ -1029,51 +1073,55 @@ elm_send(struct diag_l0_device *dl0d, /* * Get data (blocking), returns number of bytes read, between 1 and len - * ELM returns a string with format "%02X %02X %02X[...]\n" . But it's slow so we add ELM_SLOWNESS ms to the specified timeout. - * We convert this received ascii string to hex before returning. - * note : "len" is the number of bytes read on the OBD bus, *NOT* the number of ASCII chars received on the serial link ! + * ELM returns a string with format "%02X %02X %02X[...]\n" . But it's slow so we add + *ELM_SLOWNESS ms to the specified timeout. We convert this received ascii string to hex + *before returning. note : "len" is the number of bytes read on the OBD bus, *NOT* the + *number of ASCII chars received on the serial link ! * TODO decode possible error strings ! Essential because ELM can reply * "FB ERROR" (FB) is a valid hex number * "ACT ALARM" (AC) is a valid hex number * technique: * -if any hexpair doesn't decode cleanly, discard message * -just before returning any data, search for an error message match - * -still missing : if caller requests 1 byte, and the error is "FB ERROR", we'll still happily return 0xFB ! + * -still missing : if caller requests 1 byte, and the error is "FB ERROR", we'll + *still happily return 0xFB ! * - * TODO: improve "len" semantics for L0 interfaces that do framing, such as this. Currently this returns max 1 message, to - * let L2 do another call to get further messages (typical case of multiple responses) + * TODO: improve "len" semantics for L0 interfaces that do framing, such as this. Currently + *this returns max 1 message, to let L2 do another call to get further messages (typical + *case of multiple responses) */ static int -elm_recv(struct diag_l0_device *dl0d, - UNUSED(const char *subinterface), void *data, size_t len, unsigned int timeout) { +elm_recv(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), void *data, + size_t len, unsigned int timeout) { int rv, xferd; struct elm_device *dev = dl0d->l0_int; - uint8_t rxbuf[3*MAXRBUF +1]; //I think some hotdog code in L2/L3 calls _recv with MAXRBUF so this needs to be huge. - //the +1 is to \0-terminate the buffer for elm_parse_errors() to work - - unsigned long t0,tf; //manual timeout control - int steplen; /* bytes per read */ - int wp, rp; /* write & read indexes in rxbuf; a type of FIFO */ + uint8_t rxbuf[3 * MAXRBUF + 1]; // I think some hotdog code in L2/L3 calls _recv + // with MAXRBUF so this needs to be huge. the +1 is + // to \0-terminate the buffer for + // elm_parse_errors() to work + + unsigned long t0, tf; // manual timeout control + int steplen; /* bytes per read */ + int wp, rp; /* write & read indexes in rxbuf; a type of FIFO */ const char *err; if ((!len) || (len > MAXRBUF)) { return diag_iseterr(DIAG_ERR_BADLEN); } - t0=diag_os_getms(); - tf=t0+timeout + ELM_SLOWNESS; //timeout when tf is reached + t0 = diag_os_getms(); + tf = t0 + timeout + ELM_SLOWNESS; // timeout when tf is reached - steplen=2; - wp=0; - rp=0; - xferd=0; - rxbuf[0] = 0x00; //null-terminate + steplen = 2; + wp = 0; + rp = 0; + xferd = 0; + rxbuf[0] = 0x00; // null-terminate - if (diag_l0_debug & DIAG_DEBUG_READ) { + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, - FLFMT - "Expecting 3*%d bytes from ELM, %u ms timeout(+400)...", - FL, (int)len, timeout); + FLFMT "Expecting 3*%d bytes from ELM, %u ms timeout(+400)...", FL, + (int)len, timeout); } while (1) { @@ -1088,7 +1136,7 @@ elm_recv(struct diag_l0_device *dl0d, } timeout = tf - tcur; - rv = diag_tty_read(dev->tty_int, rxbuf+wp, steplen, timeout); + rv = diag_tty_read(dev->tty_int, rxbuf + wp, steplen, timeout); if (rv == DIAG_ERR_TIMEOUT) { goto pre_exit; } @@ -1098,15 +1146,15 @@ elm_recv(struct diag_l0_device *dl0d, return diag_iseterr(DIAG_ERR_GENERAL); } - wp += rv; /* position for next tty_read */ - rxbuf[wp]=0; // '\0'-terminate "string" + wp += rv; /* position for next tty_read */ + rxbuf[wp] = 0; // '\0'-terminate "string" - int skipc; /* chars to skip */ + int skipc; /* chars to skip */ - skipc = strspn((char *)(&rxbuf[rp]), " "); /* skip contig spaces */ + skipc = strspn((char *)(&rxbuf[rp]), " "); /* skip contig spaces */ rp += skipc; /* line end ? */ - skipc=strspn((char *)(&rxbuf[rp]), "\r\n>"); + skipc = strspn((char *)(&rxbuf[rp]), "\r\n>"); rp += skipc; if (skipc > 0) { /* definitely a line-end / prompt ! return data so far, if any */ @@ -1117,26 +1165,28 @@ elm_recv(struct diag_l0_device *dl0d, if (strlen((char *)(&rxbuf[rp])) < 2) { /* probably incomplete hexpair. */ - steplen=1; + steplen = 1; continue; } unsigned int rbyte; if (sscanf((char *)(&rxbuf[rp]), "%02X", &rbyte) == 1) { /* good hexpair */ - ((uint8_t *)data)[xferd]=(uint8_t) rbyte; + ((uint8_t *)data)[xferd] = (uint8_t)rbyte; xferd++; - if ( (size_t)xferd==len) { + if ((size_t)xferd == len) { goto pre_exit; } } else { /* didn't scanf properly... error message ? ex. "NO DATA\r>" * NO DATA is pretty inoffensive; skip printing that one */ - if (!(rxbuf[rp] == 'N' && rxbuf[rp+1] =='O')) { - fprintf(stderr, FLFMT "ELM sscanf failed to eat '%s'\n", FL, rxbuf); + if (!(rxbuf[rp] == 'N' && rxbuf[rp + 1] == 'O')) { + fprintf(stderr, FLFMT "ELM sscanf failed to eat '%s'\n", + FL, rxbuf); } /* finish pulling the error message or whatever garbage */ - rv = diag_tty_read(dev->tty_int, rxbuf+wp, sizeof(rxbuf) - wp, ELM_SLOWNESS); + rv = diag_tty_read(dev->tty_int, rxbuf + wp, sizeof(rxbuf) - wp, + ELM_SLOWNESS); if (rv >= 0) { rxbuf[wp + rv] = 0x00; } @@ -1144,28 +1194,29 @@ elm_recv(struct diag_l0_device *dl0d, goto pre_exit; } /* here, we just sscanf'd 2 bytes, so we read 1 more. */ - /* we can't read 2 more, in case we're in a multi-message, for instance if we just decoded 0x00 in - * "48 6A 01 00\n48 6A..." , reading two bytes "\n4" would corrupt the next message ! + /* we can't read 2 more, in case we're in a multi-message, for instance if + * we just decoded 0x00 in "48 6A 01 00\n48 6A..." , reading two bytes + * "\n4" would corrupt the next message ! */ rp += 2; - steplen=1; - } // while (1) + steplen = 1; + } // while (1) pre_exit: - err = elm_parse_errors(dl0d, rxbuf); - if (err) { - if (strcmp(err, "NO DATA") == 0) { - return DIAG_ERR_TIMEOUT; - } - fprintf(stderr, FLFMT "ELM error %s\n", FL, err); - return diag_iseterr(DIAG_ERR_GENERAL); + err = elm_parse_errors(dl0d, rxbuf); + if (err) { + if (strcmp(err, "NO DATA") == 0) { + return DIAG_ERR_TIMEOUT; } - return (xferd>0)? xferd:DIAG_ERR_TIMEOUT; + fprintf(stderr, FLFMT "ELM error %s\n", FL, err); + return diag_iseterr(DIAG_ERR_GENERAL); + } + return (xferd > 0) ? xferd : DIAG_ERR_TIMEOUT; } - /* set new wakeup message, if possible */ -static int elm_setwm(struct diag_l0_device *dl0d, struct diag_msg *pmsg) { +static int +elm_setwm(struct diag_l0_device *dl0d, struct diag_msg *pmsg) { struct elm_device *dev; dev = (struct elm_device *)dl0d->l0_int; @@ -1175,17 +1226,21 @@ static int elm_setwm(struct diag_l0_device *dl0d, struct diag_msg *pmsg) { * It's possible to change the wakeup message after init, * but we don't currently implement this. */ - fprintf(stderr, FLFMT "elm_setwm: tried to set wakeup message after init\n", FL); + fprintf(stderr, + FLFMT "elm_setwm: tried to set wakeup message after init\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } if (dev->elmflags & ELM_323_BASIC) { - fprintf(stderr, FLFMT "elm_setwm: ELM323 doesn't support setting wakeup message\n", FL); + fprintf(stderr, + FLFMT "elm_setwm: ELM323 doesn't support setting wakeup message\n", + FL); return diag_iseterr(DIAG_ERR_IOCTL_NOTSUPP); } if (pmsg->len != 4) { - fprintf(stderr, FLFMT "elm_setwm: invalid message length %d\n", FL, pmsg->len); + fprintf(stderr, FLFMT "elm_setwm: invalid message length %d\n", FL, + pmsg->len); return diag_iseterr(DIAG_ERR_GENERAL); } @@ -1199,45 +1254,46 @@ static int elm_setwm(struct diag_l0_device *dl0d, struct diag_msg *pmsg) { return 0; } - static uint32_t elm_getflags(struct diag_l0_device *dl0d) { struct elm_device *dev; - uint32_t flags=0; + uint32_t flags = 0; dev = (struct elm_device *)dl0d->l0_int; flags = DIAG_L1_DATAONLY | DIAG_L1_AUTOSPEED | DIAG_L1_DOESP4WAIT | - DIAG_L1_DOESL2FRAME | DIAG_L1_DOESL2CKSUM | DIAG_L1_DOESFULLINIT | DIAG_L1_DOESKEEPALIVE; + DIAG_L1_DOESL2FRAME | DIAG_L1_DOESL2CKSUM | DIAG_L1_DOESFULLINIT | + DIAG_L1_DOESKEEPALIVE; switch (dev->protocol) { case DIAG_L1_ISO9141: flags |= DIAG_L1_SLOW; flags &= ~DIAG_L1_DATAONLY; - //flags |= DIAG_L1_NOHDRS; //probably not needed since we send ATH1 on init (enable headers) + // flags |= DIAG_L1_NOHDRS; //probably not needed since we send ATH1 on + // init (enable headers) break; case DIAG_L1_ISO14230: flags |= DIAG_L1_SLOW | DIAG_L1_FAST | DIAG_L1_PREFFAST; - //flags |= DIAG_L1_NOHDRS; + // flags |= DIAG_L1_NOHDRS; break; default: break; } - if (diag_l0_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "getflags link %p proto %d flags 0x%X\n", - FL, (void *)dl0d, dev->protocol, flags); + if (diag_l0_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "getflags link %p proto %d flags 0x%X\n", FL, + (void *)dl0d, dev->protocol, flags); } return flags; - } -//elm_parse_cr : change 0x0A to 0x0D in datastream. -static void elm_parse_cr(uint8_t *data, int len) { - int i=0; - for (;i>=1) { - if (bit_point & *byte_point) { // case for new bit = 1 + for (i = 0, byte_point = msg_buf; i < nbytes; ++i, ++byte_point) { + for (j = 0, bit_point = 0x80; j < 8; ++j, bit_point >>= 1) { + if (bit_point & *byte_point) { // case for new bit = 1 if (crc_reg & 0x80) { - poly=1; // define the polynomial + poly = 1; // define the polynomial } else { poly = 0x1c; } - crc_reg= ( (crc_reg << 1) | 1) ^ poly; - } else { // case for new bit = 0 - poly=0; + crc_reg = ((crc_reg << 1) | 1) ^ poly; + } else { // case for new bit = 0 + poly = 0; if (crc_reg & 0x80) { poly = 0x1d; } - crc_reg= (crc_reg << 1) ^ poly; + crc_reg = (crc_reg << 1) ^ poly; } } } - return ~crc_reg; // Return CRC + return ~crc_reg; // Return CRC } -/* parse an ME response buffer, and return the actual payload length (including checksum / CRC byte) by - * trying to find the longest message with a valid checksum or CRC. +/* parse an ME response buffer, and return the actual payload length (including checksum / + * CRC byte) by trying to find the longest message with a valid checksum or CRC. * Limitations : - * 1- ISO payloads that really have 0 as their checksum will be reported as maximum-length, i.e. - * the checksum for [0xFF 0x01] is 0; but the function will report the actual message is - * [FF 01 00 .... 00] which also has a valid checksum. + * 1- ISO payloads that really have 0 as their checksum will be reported as maximum-length, + * i.e. the checksum for [0xFF 0x01] is 0; but the function will report the actual message + * is [FF 01 00 .... 00] which also has a valid checksum. * * 2- J1850 CRC is less problematic; not sure if there can be collisions such as - * [X1 ... Xn] where Xn is the valid CRC when calculated on X1..X(n-1) , while at the same time respecting - * [X1 ... Xn Z1 Z2 .. Zn] where Z1..Zn are 0, and that the CRC of X1...Z(n-1) is 0x00 !? + * [X1 ... Xn] where Xn is the valid CRC when calculated on X1..X(n-1) , while at the same + * time respecting [X1 ... Xn Z1 Z2 .. Zn] where Z1..Zn are 0, and that the CRC of + * X1...Z(n-1) is 0x00 !? */ static unsigned me_guess_rxlen(uint8_t *buf) { /* Response format : - * buf[1]=type; buf[2]: payload, padded with 0 bytes at the end; buf[13] : ME checksum (ignored here) + * buf[1]=type; buf[2]: payload, padded with 0 bytes at the end; buf[13] : ME + * checksum (ignored here) */ unsigned len; - for (len=10; len > 0; len--) { + for (len = 10; len > 0; len--) { uint8_t msg_type = buf[1]; // verify if checksum/CRC works with this length: @@ -284,8 +512,8 @@ me_guess_rxlen(uint8_t *buf) { } // was the last byte 0, therefore possibly just padding ? - if (buf[2+len] != 0) { - //not padding : can't continue. + if (buf[2 + len] != 0) { + // not padding : can't continue. break; } } @@ -297,7 +525,8 @@ me_guess_rxlen(uint8_t *buf) { * Open the diagnostic device, returns a file descriptor * records original state of term interface so we can restore later */ -static int muleng_open(struct diag_l0_device *dl0d, int iProtocol) { +static int +muleng_open(struct diag_l0_device *dl0d, int iProtocol) { int rv; struct muleng_device *dev; struct diag_serial_settings set; @@ -307,9 +536,9 @@ static int muleng_open(struct diag_l0_device *dl0d, int iProtocol) { assert(dl0d); dev = dl0d->l0_int; - if (diag_l0_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "open port %s L1proto %d\n", - FL, dev->port.val.str, iProtocol); + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "open port %s L1proto %d\n", FL, dev->port.val.str, + iProtocol); } dev->protocol = iProtocol; @@ -327,24 +556,23 @@ static int muleng_open(struct diag_l0_device *dl0d, int iProtocol) { set.stopbits = diag_stopbits_1; set.parflag = diag_par_n; - if ((rv=diag_tty_setup(dev->tty_int, &set))) { + if ((rv = diag_tty_setup(dev->tty_int, &set))) { muleng_close(dl0d); return diag_iseterr(rv); } /* And set DTR high and RTS low to power the device */ - if ((rv=diag_tty_control(dev->tty_int, 1, 0))) { + if ((rv = diag_tty_control(dev->tty_int, 1, 0))) { muleng_close(dl0d); return diag_iseterr(rv); } - diag_tty_iflush(dev->tty_int); /* Flush unread input */ + diag_tty_iflush(dev->tty_int); /* Flush unread input */ dl0d->opened = 1; - return 0 ; + return 0; } - static int muleng_new(struct diag_l0_device *dl0d) { struct muleng_device *dev; @@ -378,7 +606,8 @@ muleng_new(struct diag_l0_device *dl0d) { return 0; } -static void muleng_del(struct diag_l0_device *dl0d) { +static void +muleng_del(struct diag_l0_device *dl0d) { struct muleng_device *dev; assert(dl0d); @@ -394,7 +623,8 @@ static void muleng_del(struct diag_l0_device *dl0d) { return; } -static struct cfgi *muleng_getcfg(struct diag_l0_device *dl0d) { +static struct cfgi * +muleng_getcfg(struct diag_l0_device *dl0d) { struct muleng_device *dev; if (dl0d == NULL) { return diag_pseterr(DIAG_ERR_BADCFG); @@ -404,7 +634,6 @@ static struct cfgi *muleng_getcfg(struct diag_l0_device *dl0d) { return &dev->port; } - static void muleng_close(struct diag_l0_device *dl0d) { if (!dl0d) { @@ -412,7 +641,7 @@ muleng_close(struct diag_l0_device *dl0d) { } struct muleng_device *dev = dl0d->l0_int; - if (diag_l0_debug & DIAG_DEBUG_CLOSE) { + if (diag_l0_debug_load() & DIAG_DEBUG_CLOSE) { fprintf(stderr, FLFMT "link %p closing\n", FL, (void *)dl0d); } @@ -435,10 +664,10 @@ muleng_write(struct diag_l0_device *dl0d, const void *dp, size_t txlen) { return diag_iseterr(DIAG_ERR_BADLEN); } - if ( (diag_l0_debug & (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA)) == - (DIAG_DEBUG_WRITE|DIAG_DEBUG_DATA) ) { - fprintf(stderr, FLFMT "device link %p sending to ME device: ", - FL, (void *)dl0d); + if ((diag_l0_debug_load() & (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) == + (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) { + fprintf(stderr, FLFMT "device link %p sending to ME device: ", FL, + (void *)dl0d); diag_data_dump(stderr, dp, txlen); fprintf(stderr, "\n"); } @@ -446,7 +675,7 @@ muleng_write(struct diag_l0_device *dl0d, const void *dp, size_t txlen) { /* * And send it to the interface */ - if (diag_tty_write(dev->tty_int, dp, txlen) != (int) txlen) { + if (diag_tty_write(dev->tty_int, dp, txlen) != (int)txlen) { fprintf(stderr, FLFMT "muleng_write error!!\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } @@ -454,7 +683,6 @@ muleng_write(struct diag_l0_device *dl0d, const void *dp, size_t txlen) { return 0; } - /* * Do 5 Baud initialisation * @@ -463,7 +691,7 @@ muleng_write(struct diag_l0_device *dl0d, const void *dp, size_t txlen) { * a tester present message */ static int -muleng_slowinit( struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in, +muleng_slowinit(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in, struct muleng_device *dev) { /* * Slow init @@ -479,13 +707,13 @@ muleng_slowinit( struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in, switch (dev->protocol) { case DIAG_L1_ISO9141: - txbuf[1] = 0x20; /* Raw mode 5 baud init */ + txbuf[1] = 0x20; /* Raw mode 5 baud init */ txbuf[2] = in->addr; break; case DIAG_L1_ISO14230: txbuf[1] = 0x85; - txbuf[2] = 0x01; /* One byte message */ - txbuf[3] = DIAG_KW2K_SI_TP; /* tester present */ + txbuf[2] = 0x01; /* One byte message */ + txbuf[3] = DIAG_KW2K_SI_TP; /* tester present */ break; } @@ -522,9 +750,8 @@ muleng_slowinit( struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in, } baud = me_baud_table[rxbuf[0]]; - if (diag_l0_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, - FLFMT "device link %p setting baud to %u\n", FL, + if (diag_l0_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "device link %p setting baud to %u\n", FL, (void *)dl0d, baud); } @@ -555,7 +782,7 @@ muleng_slowinit( struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in, } /* - * Now send the "get keybyte" request, and wait for + * Now send the "get keybyte" request, and wait for * response */ memset(txbuf, 0, sizeof(txbuf)); @@ -586,7 +813,6 @@ muleng_slowinit( struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in, break; } - return rv; } @@ -607,10 +833,8 @@ muleng_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { return diag_iseterr(DIAG_ERR_GENERAL); } - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { - fprintf(stderr, - FLFMT - "device link %p info %p initbus type %d proto %d\n", + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { + fprintf(stderr, FLFMT "device link %p info %p initbus type %d proto %d\n", FL, (void *)dl0d, (void *)dev, in->type, dev->protocol); } @@ -636,9 +860,8 @@ muleng_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { * will have been done by the slowinit() code */ static int -muleng_send(struct diag_l0_device *dl0d, -UNUSED(const char *subinterface), -const void *data, size_t len) { +muleng_send(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), + const void *data, size_t len) { int rv; uint8_t cmd; @@ -656,10 +879,10 @@ const void *data, size_t len) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l0_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "device link %p send %ld bytes protocol %d ", - FL, (void *)dl0d, (long)len, dev->protocol); - if (diag_l0_debug & DIAG_DEBUG_DATA) { + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "device link %p send %ld bytes protocol %d ", FL, + (void *)dl0d, (long)len, dev->protocol); + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { diag_data_dump(stderr, data, len); fprintf(stderr, "\n"); } @@ -686,7 +909,7 @@ const void *data, size_t len) { } else { cmd = 0x88; } - dev->dev_wakeup = 0; /* We've done the wakeup now */ + dev->dev_wakeup = 0; /* We've done the wakeup now */ break; case DIAG_L1_J1850_VPW: @@ -713,7 +936,7 @@ const void *data, size_t len) { txbuf[0] = dev->dev_addr.val.u8; txbuf[1] = cmd; - txbuf[2] = (uint8_t) len; + txbuf[2] = (uint8_t)len; memcpy(&txbuf[3], data, len); (void)muleng_txcksum(txbuf); @@ -739,9 +962,8 @@ const void *data, size_t len) { */ static int -muleng_recv(struct diag_l0_device *dl0d, -UNUSED(const char *subinterface), -void *data, size_t len, unsigned int timeout) { +muleng_recv(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), void *data, + size_t len, unsigned int timeout) { ssize_t xferd; int rv; uint8_t *pdata = (uint8_t *)data; @@ -753,7 +975,7 @@ void *data, size_t len, unsigned int timeout) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l0_debug & DIAG_DEBUG_READ) { + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "link %p recv upto %ld bytes timeout %u, rxlen %d " @@ -779,8 +1001,7 @@ void *data, size_t len, unsigned int timeout) { dev->dev_state = MULENG_STATE_KWP_SENDKB2; return 1; } - return 0; /* Strange, user asked for 0 bytes */ - + return 0; /* Strange, user asked for 0 bytes */ case MULENG_STATE_KWP_SENDKB2: if (len >= 1) { @@ -788,14 +1009,13 @@ void *data, size_t len, unsigned int timeout) { dev->dev_state = MULENG_STATE_OPEN; return 1; } - return 0; /* Strange, user asked for 0 bytes */ - + return 0; /* Strange, user asked for 0 bytes */ case MULENG_STATE_RAW: xferd = diag_tty_read(dev->tty_int, data, len, timeout); - if (diag_l0_debug & DIAG_DEBUG_READ) { - fprintf(stderr, FLFMT "link %p read %ld bytes\n", FL, - (void *)dl0d, (long)xferd); + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "link %p read %ld bytes\n", FL, (void *)dl0d, + (long)xferd); } return xferd; @@ -804,7 +1024,7 @@ void *data, size_t len, unsigned int timeout) { timeout = 200; dev->dev_state = MULENG_STATE_OPEN; /* Drop thru */ - default: /* Some other mode */ + default: /* Some other mode */ break; } @@ -823,11 +1043,11 @@ void *data, size_t len, unsigned int timeout) { if (bufbytes <= len) { memcpy(data, &dev->dev_rxbuf[dev->dev_rdoffset], bufbytes); dev->dev_rxlen = dev->dev_rdoffset = dev->resp_len = 0; - return (int) bufbytes; + return (int)bufbytes; } memcpy(data, &dev->dev_rxbuf[dev->dev_rdoffset], len); dev->dev_rdoffset += len; - return (int) len; + return (int)len; } /* @@ -836,7 +1056,7 @@ void *data, size_t len, unsigned int timeout) { */ rv = diag_tty_read(dev->tty_int, &dev->dev_rxbuf[dev->dev_rxlen], - (size_t)(14 - dev->dev_rxlen), timeout); + (size_t)(14 - dev->dev_rxlen), timeout); if (rv == DIAG_ERR_TIMEOUT) { return DIAG_ERR_TIMEOUT; } @@ -852,9 +1072,8 @@ void *data, size_t len, unsigned int timeout) { } /* OK, got whole message */ - if (diag_l0_debug & DIAG_DEBUG_READ) { - fprintf(stderr, - FLFMT "link %p received from ME: ", FL, (void *)dl0d); + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "link %p received from ME: ", FL, (void *)dl0d); diag_data_dump(stderr, dev->dev_rxbuf, dev->dev_rxlen); fprintf(stderr, "\n"); } @@ -864,15 +1083,15 @@ void *data, size_t len, unsigned int timeout) { xferd = diag_cks1(&dev->dev_rxbuf[1], 12); if ((xferd & 0xff) != dev->dev_rxbuf[13]) { -/* XXX, we should deal with this properly rather than just printing a message */ - fprintf(stderr,"Got bad checksum from ME device 0x%X != 0x%X\n", - (int) xferd & 0xff, dev->dev_rxbuf[13]); - fprintf(stderr,"PC Serial port probably out of spec.\nRX Data: "); + /* XXX, we should deal with this properly rather than just printing a + * message */ + fprintf(stderr, "Got bad checksum from ME device 0x%X != 0x%X\n", + (int)xferd & 0xff, dev->dev_rxbuf[13]); + fprintf(stderr, "PC Serial port probably out of spec.\nRX Data: "); diag_data_dump(stderr, dev->dev_rxbuf, dev->dev_rxlen); fprintf(stderr, "\n"); } - /* * Check the type */ @@ -881,7 +1100,7 @@ void *data, size_t len, unsigned int timeout) { dev->dev_rxlen = 0; dev->resp_len = 0; - if (diag_l0_debug & DIAG_DEBUG_READ) { + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "link %p ME returns err 0x%X : %s; s/w v 0x%X " @@ -892,17 +1111,17 @@ void *data, size_t len, unsigned int timeout) { } 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 */ + 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; break; default: - if ( !(diag_l0_debug & DIAG_DEBUG_READ)) { - //don't print the error twice + if (!(diag_l0_debug_load() & DIAG_DEBUG_READ)) { + // don't print the error twice fprintf(stderr, FLFMT "ME : error 0x%0X, %s\n.", FL, - dev->dev_rxbuf[3], me_geterr(dev->dev_rxbuf[3]) ); + dev->dev_rxbuf[3], me_geterr(dev->dev_rxbuf[3])); } return diag_iseterr(DIAG_ERR_GENERAL); } @@ -912,14 +1131,14 @@ void *data, size_t len, unsigned int timeout) { /* get actual bus message length without padding 0x00 bytes */ dev->resp_len = me_guess_rxlen(dev->dev_rxbuf); - dev->dev_rdoffset = 2; /* Skip the ME header */ + dev->dev_rdoffset = 2; /* Skip the ME header */ /* Copy data to user */ xferd = MIN(len, dev->resp_len); memcpy(data, &dev->dev_rxbuf[dev->dev_rdoffset], (size_t)xferd); dev->dev_rdoffset += xferd; - if (dev->dev_rdoffset == dev->resp_len +2) { + if (dev->dev_rdoffset == dev->resp_len + 2) { /* End of message, reset pointers */ dev->dev_rxlen = 0; dev->dev_rdoffset = 0; @@ -942,33 +1161,32 @@ muleng_getflags(struct diag_l0_device *dl0d) { switch (dev->protocol) { case DIAG_L1_J1850_VPW: case DIAG_L1_J1850_PWM: - flags |= DIAG_L1_DOESL2CKSUM; - flags |= DIAG_L1_DOESL2FRAME; - break; + 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; + 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, FLFMT "getflags link %p proto %d flags 0x%X\n", - FL, (void *)dl0d, dev->protocol, flags); + if (diag_l0_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "getflags link %p proto %d flags 0x%X\n", FL, + (void *)dl0d, dev->protocol, flags); } - return flags ; + return flags; } - -static int muleng_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { +static int +muleng_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { int rv = 0; switch (cmd) { @@ -976,7 +1194,7 @@ static int muleng_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { rv = muleng_initbus(dl0d, (struct diag_l1_initbus_args *)data); break; case DIAG_IOCTL_IFLUSH: - //do nothing + // do nothing rv = 0; break; default: @@ -987,19 +1205,17 @@ static int muleng_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { return rv; } -const struct diag_l0 diag_l0_me = { - "Multiplex Engineering T16 interface", - "MET16", - DIAG_L1_J1850_VPW | DIAG_L1_J1850_PWM | - DIAG_L1_ISO9141 | DIAG_L1_ISO14230, - muleng_init, - muleng_new, - muleng_getcfg, - muleng_del, - muleng_open, - muleng_close, - muleng_getflags, - muleng_recv, - muleng_send, - muleng_ioctl -}; +const struct diag_l0 diag_l0_me = {"Multiplex Engineering T16 interface", + "MET16", + DIAG_L1_J1850_VPW | DIAG_L1_J1850_PWM | + DIAG_L1_ISO9141 | DIAG_L1_ISO14230, + muleng_init, + muleng_new, + muleng_getcfg, + muleng_del, + muleng_open, + muleng_close, + muleng_getflags, + muleng_recv, + muleng_send, + muleng_ioctl}; diff --git a/scantool/diag_l0_sim.c b/scantool/diag_l0_sim.c index 8dad31ec..f4542e2f 100644 --- a/scantool/diag_l0_sim.c +++ b/scantool/diag_l0_sim.c @@ -56,22 +56,19 @@ #include "utlist.h" - /**************************************************/ // LOCAL DATATYPES AND GLOBALS: /**************************************************/ - extern const struct diag_l0 diag_l0_sim; -const char *simfile_default=DB_FILE; //default filename - +const char *simfile_default = DB_FILE; // default filename // ECU responses linked list: struct sim_ecu_response { - char *text; // unparsed text for the response! + char *text; // unparsed text for the response! uint8_t *data; // parsed final response. - uint8_t len; // final response length. + uint8_t len; // final response length. struct sim_ecu_response *next; }; @@ -85,35 +82,31 @@ struct sim_device { // or not the L2 framing and CRC/Checksums. // These boolean flags are to be programmed with values // from the DB file in use. - bool dataonly; /* messages are sent/received without headers or checksums; required for J1850 */ - bool nocksum; /* messages are sent/received without checksums */ - bool framed; /* responses must be considered as complete frames; dataonly and nocksum imply this */ - bool fullinit; /* indicate that l0 does full init */ + bool dataonly; /* messages are sent/received without headers or checksums; required + for J1850 */ + bool nocksum; /* messages are sent/received without checksums */ + bool framed; /* responses must be considered as complete frames; dataonly and + nocksum imply this */ + bool fullinit; /* indicate that l0 does full init */ - int proto_restrict; /* (optional) only accept connections matching this proto */ + int proto_restrict; /* (optional) only accept connections matching this proto */ struct cfgi simfile; - uint8_t sim_last_ecu_request[255]; // Copy of most recent request. - struct sim_ecu_response *sim_last_ecu_responses; // For keeping all the responses to the last request. + uint8_t sim_last_ecu_request[255]; // Copy of most recent request. + struct sim_ecu_response *sim_last_ecu_responses; // For keeping all the responses + // to the last request. }; - - /**************************************************/ // FORWARD DECLARATIONS: /**************************************************/ +static int sim_send(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), + const void *data, size_t len); -static int -sim_send(struct diag_l0_device *dl0d, - UNUSED(const char *subinterface), - const void *data, size_t len); - -static int -sim_recv(struct diag_l0_device *dl0d, - UNUSED(const char *subinterface), - void *data, size_t len, unsigned int timeout); +static int sim_recv(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), + void *data, size_t len, unsigned int timeout); static void sim_close(struct diag_l0_device *dl0d); @@ -121,10 +114,9 @@ static void sim_close(struct diag_l0_device *dl0d); // LOCAL FUNCTIONS: /**************************************************/ - // Allocates one new ecu response and fills it with given text. -struct sim_ecu_response -*sim_new_ecu_response_txt(const char *text) { +struct sim_ecu_response * +sim_new_ecu_response_txt(const char *text) { struct sim_ecu_response *resp; int rv; @@ -138,12 +130,13 @@ struct sim_ecu_response resp->next = NULL; if ((text != NULL) && strlen(text)) { - if ((rv=diag_calloc(&(resp->text), strlen(text)+1))) { + if ((rv = diag_calloc(&(resp->text), strlen(text) + 1))) { free(resp); return diag_pseterr(rv); } - strncpy(resp->text, text, strlen(text)); //using strlen() defeats the purpose of strncpy ... + strncpy(resp->text, text, strlen(text)); // using strlen() defeats the + // purpose of strncpy ... } return resp; @@ -151,8 +144,8 @@ struct sim_ecu_response // Allocates one new ecu response and fills it with given data. // (not used yet, here for "just in case") -struct sim_ecu_response -*sim_new_ecu_response_bin(const uint8_t *data, const uint8_t len) { +struct sim_ecu_response * +sim_new_ecu_response_bin(const uint8_t *data, const uint8_t len) { struct sim_ecu_response *resp; int rv; @@ -179,16 +172,16 @@ struct sim_ecu_response } // Frees an ecu response and returns the next one in the list. -struct sim_ecu_response -*sim_free_ecu_response(struct sim_ecu_response **resp) { - struct sim_ecu_response* next_resp = NULL; +struct sim_ecu_response * +sim_free_ecu_response(struct sim_ecu_response **resp) { + struct sim_ecu_response *next_resp = NULL; if (resp && *resp) { - //get pointer to next one. + // get pointer to next one. next_resp = (*resp)->next; - //free this one. + // free this one. if ((*resp)->data) { free((*resp)->data); } @@ -199,13 +192,13 @@ struct sim_ecu_response *resp = NULL; } - //return next one. + // return next one. return next_resp; } - // Frees all responses from the given one until the end of the list. -void sim_free_ecu_responses(struct sim_ecu_response **resp_pp) { +void +sim_free_ecu_responses(struct sim_ecu_response **resp_pp) { struct sim_ecu_response **temp_resp_pp = resp_pp; uint8_t count = 0; @@ -218,15 +211,15 @@ void sim_free_ecu_responses(struct sim_ecu_response **resp_pp) { count++; } - if (diag_l0_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT " %d responses freed from queue.\n", FL, - count); + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT " %d responses freed from queue.\n", FL, count); } return; } // for debug purposes. -void sim_dump_ecu_responses(struct sim_ecu_response *resp_p) { +void +sim_dump_ecu_responses(struct sim_ecu_response *resp_p) { struct sim_ecu_response *tresp; uint8_t count = 0; @@ -238,23 +231,24 @@ void sim_dump_ecu_responses(struct sim_ecu_response *resp_p) { fprintf(stderr, FLFMT "%d responses in queue.\n", FL, count); } - // Builds a list of responses for a request, by finding them in the DB file. -void sim_find_responses(struct sim_ecu_response **resp_pp, FILE *fp, const uint8_t *data, const uint8_t len) { +void +sim_find_responses(struct sim_ecu_response **resp_pp, FILE *fp, const uint8_t *data, + const uint8_t len) { #define TAG_REQUEST "RQ" #define TAG_RESPONSE "RP" #define VALUE_DONTCARE "XXXX" -#define REQBYTES 11 //number of request bytes analyzed +#define REQBYTES 11 // number of request bytes analyzed uint8_t resp_count = 0; uint8_t new_resp_count = 0; uint8_t synth_req[REQBYTES]; - char line_buf[1280+1]; // 255 response bytes * 5 ("0xYY ") + tolerance for a token ("abc1 ") = 1280. + char line_buf[1280 + 1]; // 255 response bytes * 5 ("0xYY ") + tolerance for a + // token ("abc1 ") = 1280. int end_responses = 0; int request_found = 0; struct sim_ecu_response *resp_p; - // walk to the end of the list (last valid item). LL_FOREACH(*resp_pp, resp_p) { resp_count++; @@ -278,7 +272,7 @@ void sim_find_responses(struct sim_ecu_response **resp_pp, FILE *fp, const uint8 unsigned int i, num; char *p, *q; p = line_buf + 3; - for (i=0; i < REQBYTES; i++) { + for (i = 0; i < REQBYTES; i++) { while (isspace(*p)) { p++; } @@ -314,28 +308,44 @@ void sim_find_responses(struct sim_ecu_response **resp_pp, FILE *fp, const uint8 break; } // ignore all lines except responses. - if (strncmp(line_buf, TAG_RESPONSE, strlen(TAG_RESPONSE)) != 0) { + if (strncmp(line_buf, TAG_RESPONSE, + strlen(TAG_RESPONSE)) != 0) { // if it's another request, then end the list. - if (strncmp(line_buf, TAG_REQUEST, strlen(TAG_REQUEST)) == 0) { + if (strncmp(line_buf, TAG_REQUEST, + strlen(TAG_REQUEST)) == 0) { end_responses = 1; - break; + break; } continue; } // add the new response (without the tag). if (resp_count + new_resp_count == 0) { // create the root of the list. - resp_p = *resp_pp = sim_new_ecu_response_txt(line_buf + strlen(TAG_RESPONSE) + 1); + resp_p = *resp_pp = sim_new_ecu_response_txt( + line_buf + strlen(TAG_RESPONSE) + 1); if (!resp_p) { - fprintf(stderr, FLFMT "Could not add new response \"%s\"\n", FL, line_buf + strlen(TAG_RESPONSE) + 1); - end_responses=1; + fprintf(stderr, + FLFMT + "Could not add new response " + "\"%s\"\n", + FL, + line_buf + strlen(TAG_RESPONSE) + + 1); + end_responses = 1; } } else { // add to the end of the list. - resp_p->next = sim_new_ecu_response_txt(line_buf + strlen(TAG_RESPONSE) + 1); + resp_p->next = sim_new_ecu_response_txt( + line_buf + strlen(TAG_RESPONSE) + 1); if (!(resp_p->next)) { - fprintf(stderr, FLFMT "Could not add new response \"%s\"\n", FL, line_buf + strlen(TAG_RESPONSE) + 1); - end_responses=1; + fprintf(stderr, + FLFMT + "Could not add new response " + "\"%s\"\n", + FL, + line_buf + strlen(TAG_RESPONSE) + + 1); + end_responses = 1; } resp_p = resp_p->next; } @@ -344,31 +354,32 @@ void sim_find_responses(struct sim_ecu_response **resp_pp, FILE *fp, const uint8 } } - if (diag_l0_debug & DIAG_DEBUG_DATA) { - fprintf(stderr, - FLFMT "%d responses queued for receive, %d new.\n", FL, + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { + fprintf(stderr, FLFMT "%d responses queued for receive, %d new.\n", FL, resp_count + new_resp_count, new_resp_count); } } - // Returns a value between 0x00 and 0xFF calculated as the trigonometric // sine of the current system time (with a period of one second). -uint8_t sine1(UNUSED(uint8_t *data), UNUSED(uint8_t pos)) { - unsigned long now=diag_os_getms(); - //sin() returns a float between -1.0 and 1.0 - return (uint8_t) (0x7F * sin(now * 6.283185 / 1000)); +uint8_t +sine1(UNUSED(uint8_t *data), UNUSED(uint8_t pos)) { + unsigned long now = diag_os_getms(); + // sin() returns a float between -1.0 and 1.0 + return (uint8_t)(0x7F * sin(now * 6.283185 / 1000)); } // Returns a value between 0x00 and 0xFF directly proportional // to the value of the current system time (with a period of one second). -uint8_t sawtooth1(UNUSED(uint8_t *data), UNUSED(uint8_t pos)) { - unsigned long now=diag_os_getms(); - return (uint8_t) (0xFF * (now % 1000)); +uint8_t +sawtooth1(UNUSED(uint8_t *data), UNUSED(uint8_t pos)) { + unsigned long now = diag_os_getms(); + return (uint8_t)(0xFF * (now % 1000)); } // Returns a value copied from the specified position in the request. -uint8_t requestbyten(UNUSED(uint8_t *data), char *s, uint8_t req[]) { +uint8_t +requestbyten(UNUSED(uint8_t *data), char *s, uint8_t req[]) { int index; bool increment = 0; bool bogus = 0; @@ -378,7 +389,7 @@ uint8_t requestbyten(UNUSED(uint8_t *data), char *s, uint8_t req[]) { index = (uint8_t)strtoul(s, &p, 10); if (*s == '\0') { bogus = 1; - } else if (p[0]=='+' && p[1]=='\0') { + } else if (p[0] == '+' && p[1] == '\0') { increment = 1; } else if (*p != '\0') { bogus = 1; @@ -402,17 +413,19 @@ uint8_t requestbyten(UNUSED(uint8_t *data), char *s, uint8_t req[]) { } // Parses a response's text to data. -// Replaces special tokens with function results. This mangles resp_p->text, which shouldn't be a problem -void sim_parse_response(struct sim_ecu_response *resp_p, uint8_t req[]) { -#define TOKEN_SINE1 "sin1" +// Replaces special tokens with function results. This mangles resp_p->text, which +// shouldn't be a problem +void +sim_parse_response(struct sim_ecu_response *resp_p, uint8_t req[]) { +#define TOKEN_SINE1 "sin1" #define TOKEN_SAWTOOTH1 "swt1" #define TOKEN_ISO9141CS "cks1" #define TOKEN_REQUESTBYTE "req" #define SRESP_SIZE 255 - uint8_t synth_resp[SRESP_SIZE]; // 255 response bytes. - char *cur_tok = NULL; //current token - char *rptr = resp_p->text; //working copy of the ptr. We will mangle resp_p->text + uint8_t synth_resp[SRESP_SIZE]; // 255 response bytes. + char *cur_tok = NULL; // current token + char *rptr = resp_p->text; // working copy of the ptr. We will mangle resp_p->text int ret; int pos = 0; @@ -431,23 +444,27 @@ void sim_parse_response(struct sim_ecu_response *resp_p, uint8_t req[]) { synth_resp[pos] = diag_cks1(synth_resp, pos); } else if (strncmp(cur_tok, TOKEN_REQUESTBYTE, strlen(TOKEN_REQUESTBYTE)) == 0) { - synth_resp[pos] = requestbyten(synth_resp, cur_tok + strlen(TOKEN_REQUESTBYTE), req); + synth_resp[pos] = requestbyten( + synth_resp, cur_tok + strlen(TOKEN_REQUESTBYTE), req); } else { // failed. try scanning element as an Hex byte. unsigned int tempbyte; - ret = sscanf(cur_tok, "%X", &tempbyte); //can't scan direct to uint8 ! + ret = sscanf(cur_tok, "%X", &tempbyte); // can't scan direct to + // uint8 ! if (ret != 1) { - fprintf(stderr, FLFMT "Error parsing line: %s at position %d.\n", FL, resp_p->text, pos*5); + fprintf(stderr, + FLFMT "Error parsing line: %s at position %d.\n", + FL, resp_p->text, pos * 5); break; } - synth_resp[pos] = (uint8_t) tempbyte; + synth_resp[pos] = (uint8_t)tempbyte; } pos++; - rptr = NULL; //strtok: continue parsing + rptr = NULL; // strtok: continue parsing } // copy to user. - if (diag_calloc(&(resp_p->data),pos)) { + if (diag_calloc(&(resp_p->data), pos)) { fprintf(stderr, FLFMT "Error parsing response\n", FL); return; } @@ -457,9 +474,10 @@ void sim_parse_response(struct sim_ecu_response *resp_p, uint8_t req[]) { // Reads the configuration options from the file. // Stores them in globals. -void sim_read_cfg(struct sim_device *dev) { +void +sim_read_cfg(struct sim_device *dev) { FILE *fp = dev->fp; - char *p; // temp string pointer. + char *p; // temp string pointer. char line_buf[21]; // 20 chars generally enough for a config token. #define TAG_CFG "CFG" @@ -467,12 +485,12 @@ void sim_read_cfg(struct sim_device *dev) { #define CFG_NOL2CKSUM "NOL2CKSUM" #define CFG_FRAMED "FRAMED" #define CFG_FULLINIT "FULLINIT" -#define CFG_P9141 "P_9141" -#define CFG_P14230 "P_14230" -#define CFG_P1850P "P_J1850P" -#define CFG_P1850V "P_J1850V" -#define CFG_PCAN "P_CAN" -#define CFG_PRAW "P_RAW" +#define CFG_P9141 "P_9141" +#define CFG_P14230 "P_14230" +#define CFG_P1850P "P_J1850P" +#define CFG_P1850V "P_J1850V" +#define CFG_PCAN "P_CAN" +#define CFG_PRAW "P_RAW" dev->dataonly = 0; dev->nocksum = 0; @@ -506,22 +524,22 @@ void sim_read_cfg(struct sim_device *dev) { } else if (strncmp(p, CFG_FULLINIT, strlen(CFG_FULLINIT)) == 0) { dev->fullinit = 1; } else if (strncmp(p, CFG_P9141, strlen(CFG_P9141)) == 0) { - dev->proto_restrict=DIAG_L1_ISO9141; + dev->proto_restrict = DIAG_L1_ISO9141; continue; } else if (strncmp(p, CFG_P14230, strlen(CFG_P14230)) == 0) { - dev->proto_restrict=DIAG_L1_ISO14230; + dev->proto_restrict = DIAG_L1_ISO14230; continue; } else if (strncmp(p, CFG_P1850P, strlen(CFG_P1850P)) == 0) { - dev->proto_restrict=DIAG_L1_J1850_PWM; + dev->proto_restrict = DIAG_L1_J1850_PWM; continue; } else if (strncmp(p, CFG_P1850V, strlen(CFG_P1850V)) == 0) { - dev->proto_restrict=DIAG_L1_J1850_VPW; + dev->proto_restrict = DIAG_L1_J1850_VPW; continue; } else if (strncmp(p, CFG_PCAN, strlen(CFG_PCAN)) == 0) { - dev->proto_restrict=DIAG_L1_CAN; + dev->proto_restrict = DIAG_L1_CAN; continue; } else if (strncmp(p, CFG_PRAW, strlen(CFG_PRAW)) == 0) { - dev->proto_restrict=DIAG_L1_RAW; + dev->proto_restrict = DIAG_L1_RAW; continue; } } @@ -531,7 +549,6 @@ void sim_read_cfg(struct sim_device *dev) { // INTERFACE FUNCTIONS: /**************************************************/ - // Initializes the simulator. static int sim_init(void) { @@ -551,13 +568,13 @@ sim_new(struct diag_l0_device *dl0d) { dl0d->l0_int = dev; - //init configurable params: + // init configurable params: if (diag_cfgn_str(&dev->simfile, simfile_default, - "Simulation file to use as data input", "simfile")) { + "Simulation file to use as data input", "simfile")) { free(dev); return diag_iseterr(DIAG_ERR_GENERAL); } - dev->simfile.next = NULL; //mark as first/only/last item in the list + dev->simfile.next = NULL; // mark as first/only/last item in the list return 0; } @@ -566,7 +583,7 @@ static void sim_del(struct diag_l0_device *dl0d) { struct sim_device *dev; - assert(dl0d !=NULL); + assert(dl0d != NULL); dev = (struct sim_device *)dl0d->l0_int; @@ -588,10 +605,10 @@ sim_open(struct diag_l0_device *dl0d, int iProtocol) { assert(dl0d != NULL); - dev = (struct sim_device *) dl0d->l0_int; + dev = (struct sim_device *)dl0d->l0_int; simfile = dev->simfile.val.str; - if (diag_l0_debug & DIAG_DEBUG_OPEN) { + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "open simfile %s proto=%d\n", FL, simfile, iProtocol); } @@ -622,25 +639,22 @@ sim_open(struct diag_l0_device *dl0d, int iProtocol) { return 0; } - // Closes the simulator DB file; cleanup after _sim_open() static void sim_close(struct diag_l0_device *dl0d) { assert(dl0d != NULL); - //if (!dl0d) return; + // if (!dl0d) return; struct sim_device *dev = (struct sim_device *)dl0d->l0_int; assert(dev != NULL); // If debugging, print to stderr. - if (diag_l0_debug & DIAG_DEBUG_CLOSE) { - fprintf(stderr, FLFMT "dl0d=%p closing simfile\n", FL, - (void *)dl0d); + if (diag_l0_debug_load() & DIAG_DEBUG_CLOSE) { + fprintf(stderr, FLFMT "dl0d=%p closing simfile\n", FL, (void *)dl0d); } sim_free_ecu_responses(&dev->sim_last_ecu_responses); - if (dev->fp != NULL) { fclose(dev->fp); dev->fp = NULL; @@ -650,7 +664,6 @@ sim_close(struct diag_l0_device *dl0d) { return; } - // Simulates the bus initialization. static int sim_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { @@ -662,9 +675,8 @@ sim_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { sim_free_ecu_responses(&dev->sim_last_ecu_responses); - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { - fprintf(stderr, - FLFMT "device link %p info %p initbus type %d\n", FL, + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { + fprintf(stderr, FLFMT "device link %p info %p initbus type %d\n", FL, (void *)dl0d, (void *)dev, in->type); } @@ -680,7 +692,7 @@ sim_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { case DIAG_L1_INITBUS_FAST: // Send break. // We simulate a break with a single "0x00" char. - if (diag_l0_debug & DIAG_DEBUG_DATA) { + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { fprintf(stderr, FLFMT "Sending: BREAK!\n", FL); } sim_send(dl0d, 0, &sim_break, 1); @@ -689,7 +701,7 @@ sim_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { // Send Service Address (as if it was at 5baud). sim_send(dl0d, 0, &in->addr, 1); // Receive Synch Pattern (as if it was at 10.4kbaud). - sim_recv(dl0d, 0 , synch_patt, 1, 0); + sim_recv(dl0d, 0, synch_patt, 1, 0); break; default: return diag_iseterr(DIAG_ERR_INIT_NOTSUPP); @@ -699,16 +711,14 @@ sim_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) { return 0; } - // Simulates the send of a request. // Returns 0 on success, -1 on failure. // Should be called with the full message to send, because // CARSIM behaves like a smart interface (does P4). // Gets the list of responses from the DB file for the given request. static int -sim_send(struct diag_l0_device *dl0d, - UNUSED(const char *subinterface), - const void *data, const size_t len) { +sim_send(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), const void *data, + const size_t len) { struct sim_device *dev = dl0d->l0_int; if (len <= 0) { @@ -716,18 +726,25 @@ sim_send(struct diag_l0_device *dl0d, } if (len > 255) { - fprintf(stderr, FLFMT "Error : calling sim_send with len >255 bytes! (%u)\n", FL, (unsigned int) len); + fprintf(stderr, + FLFMT "Error : calling sim_send with len >255 bytes! (%u)\n", FL, + (unsigned int)len); return diag_iseterr(DIAG_ERR_GENERAL); } if (dev->sim_last_ecu_responses != NULL) { - fprintf(stderr, FLFMT "AAAHHH!!! You're sending a new request before reading all previous responses!!! \n", FL); + fprintf(stderr, + FLFMT + "AAAHHH!!! You're sending a new request before reading all " + "previous responses!!! \n", + FL); return diag_iseterr(DIAG_ERR_GENERAL); } - if (diag_l0_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "dl0d=%p sending %u bytes\n", FL, (void *)dl0d, (unsigned int)len); - if (diag_l0_debug & DIAG_DEBUG_DATA) { + if (diag_l0_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "dl0d=%p sending %u bytes\n", FL, (void *)dl0d, + (unsigned int)len); + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { fprintf(stderr, FLFMT "L0 sim sending: ", FL); diag_data_dump(stderr, data, len); fprintf(stderr, "\n"); @@ -738,23 +755,21 @@ sim_send(struct diag_l0_device *dl0d, memcpy(dev->sim_last_ecu_request, data, len); // Build the list of responses for this request. - sim_find_responses(&dev->sim_last_ecu_responses, dev->fp, data, (uint8_t) len); + sim_find_responses(&dev->sim_last_ecu_responses, dev->fp, data, (uint8_t)len); - if (diag_l0_debug & DIAG_DEBUG_DATA) { + if (diag_l0_debug_load() & DIAG_DEBUG_DATA) { sim_dump_ecu_responses(dev->sim_last_ecu_responses); } return 0; } - // Gets present ECU response from the prepared list. // Returns ECU response with parsed data (if applicable). // Returns number of bytes read. static int -sim_recv(struct diag_l0_device *dl0d, - UNUSED(const char *subinterface), - void *data, size_t len, unsigned int timeout) { +sim_recv(struct diag_l0_device *dl0d, UNUSED(const char *subinterface), void *data, + size_t len, unsigned int timeout) { size_t xferd; struct sim_ecu_response *resp_p = NULL; struct sim_device *dev = dl0d->l0_int; @@ -762,9 +777,8 @@ sim_recv(struct diag_l0_device *dl0d, if (!len) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l0_debug & DIAG_DEBUG_READ) { - fprintf(stderr, - FLFMT "link %p recv upto %ld bytes timeout %u\n", FL, + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "link %p recv upto %ld bytes timeout %u\n", FL, (void *)dl0d, (long)len, timeout); } @@ -777,27 +791,27 @@ sim_recv(struct diag_l0_device *dl0d, xferd = MIN(resp_p->len, len); memcpy(data, resp_p->data, xferd); // Free the present response in the list (and walk to the next one). - dev->sim_last_ecu_responses = sim_free_ecu_response(&dev->sim_last_ecu_responses); + dev->sim_last_ecu_responses = + sim_free_ecu_response(&dev->sim_last_ecu_responses); } else { // Nothing to receive, simulate timeout on return. xferd = 0; memset(data, 0, len); } - if (diag_l0_debug & DIAG_DEBUG_READ) { - fprintf(stderr, FLFMT "dl0d=%p recv %d byte;\n", FL, (void *)dl0d, (int) len); - if ((diag_l0_debug & DIAG_DEBUG_DATA) && (xferd>0)) { + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "dl0d=%p recv %d byte;\n", FL, (void *)dl0d, + (int)len); + if ((diag_l0_debug_load() & DIAG_DEBUG_DATA) && (xferd > 0)) { fprintf(stderr, FLFMT "L0 sim receiving: ", FL); diag_data_dump(stderr, data, xferd); fprintf(stderr, "\n"); } } - return (xferd == 0 ? DIAG_ERR_TIMEOUT : (int) xferd); + return (xferd == 0 ? DIAG_ERR_TIMEOUT : (int)xferd); } - - // Returns the interface's physical flags. // The simulator doesn't need half-duplex or // P4 timing, and implements all types of init. @@ -806,17 +820,13 @@ sim_getflags(struct diag_l0_device *dl0d) { struct sim_device *dev = dl0d->l0_int; int ret; - ret = DIAG_L1_SLOW | - DIAG_L1_FAST | - DIAG_L1_PREFFAST | - DIAG_L1_DOESP4WAIT | - DIAG_L1_AUTOSPEED | - DIAG_L1_NOTTY; + ret = DIAG_L1_SLOW | DIAG_L1_FAST | DIAG_L1_PREFFAST | DIAG_L1_DOESP4WAIT | + DIAG_L1_AUTOSPEED | DIAG_L1_NOTTY; - /* both "no checksum" and "dataonly" modes take care of checksums, and imply framing. */ + /* both "no checksum" and "dataonly" modes take care of checksums, and imply + * framing. */ if (dev->nocksum || dev->dataonly) { - ret |= DIAG_L1_DOESL2CKSUM | DIAG_L1_STRIPSL2CKSUM | - DIAG_L1_DOESL2FRAME; + ret |= DIAG_L1_DOESL2CKSUM | DIAG_L1_STRIPSL2CKSUM | DIAG_L1_DOESL2FRAME; } if (dev->dataonly) { @@ -834,9 +844,8 @@ sim_getflags(struct diag_l0_device *dl0d) { return ret; } - -static struct cfgi -*sim_getcfg(struct diag_l0_device *dl0d) { +static struct cfgi * +sim_getcfg(struct diag_l0_device *dl0d) { struct sim_device *dev; if (dl0d == NULL) { return diag_pseterr(DIAG_ERR_BADCFG); @@ -846,8 +855,8 @@ static struct cfgi return &dev->simfile; } - -static int sim_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { +static int +sim_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { int rv = 0; switch (cmd) { @@ -862,23 +871,22 @@ static int sim_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { return rv; } - // Declares the interface's protocol flags // and pointers to functions. // Like any simulator, it "implements" all protocols // (it only depends on the content of the DB file). -const struct diag_l0 diag_l0_sim = { - "Car Simulator interface", - "CARSIM", - DIAG_L1_J1850_VPW | DIAG_L1_J1850_PWM | DIAG_L1_ISO9141 | DIAG_L1_ISO14230 | DIAG_L1_RAW, - sim_init, - sim_new, - sim_getcfg, - sim_del, - sim_open, - sim_close, - sim_getflags, - sim_recv, - sim_send, - sim_ioctl -}; +const struct diag_l0 diag_l0_sim = {"Car Simulator interface", + "CARSIM", + DIAG_L1_J1850_VPW | DIAG_L1_J1850_PWM | + DIAG_L1_ISO9141 | DIAG_L1_ISO14230 | + DIAG_L1_RAW, + sim_init, + sim_new, + sim_getcfg, + sim_del, + sim_open, + sim_close, + sim_getflags, + sim_recv, + sim_send, + sim_ioctl}; diff --git a/scantool/diag_l1.c b/scantool/diag_l1.c index 13b960a1..f77d1cdb 100644 --- a/scantool/diag_l1.c +++ b/scantool/diag_l1.c @@ -35,7 +35,6 @@ * interfaces we use does have this (multiplex engineering interface) */ - #include #include "diag.h" @@ -45,36 +44,44 @@ #include "diag_l0.h" #include "diag_l1.h" - -int diag_l1_debug; //debug flags for l1 - - +// debug flags for l1 +DIAG_ATOMIC_STATICALLY_DECL_INIT(static diag_atomic_int diag_l1_debug) +void +diag_l1_debug_store(int d) { + diag_atomic_store_int(&diag_l1_debug, d); +} +int +diag_l1_debug_load(void) { + return diag_atomic_load_int(&diag_l1_debug); +} /* Global init flag */ -static int diag_l1_initdone=0; +static int diag_l1_initdone = 0; -//diag_l1_init : parse through l0dev_list and call each ->init() +// diag_l1_init : parse through l0dev_list and call each ->init() int diag_l1_init(void) { if (diag_l1_initdone) { return 0; } - if (diag_l1_debug & DIAG_DEBUG_INIT) { + DIAG_ATOMIC_INITSTATIC(&diag_l1_debug); + + if (diag_l1_debug_load() & DIAG_DEBUG_INIT) { fprintf(stderr, FLFMT "entered diag_l1_init\n", FL); } /* Now call the init routines for the L0 devices */ - //NOTE : ->init functions should NOT play any mem tricks (*alloc etc) or open handles. - //That way we won't need to add a diag_l0_end function. + // NOTE : ->init functions should NOT play any mem tricks (*alloc etc) or open + // handles. That way we won't need to add a diag_l0_end function. const struct diag_l0 *dl0; - int i=0; + int i = 0; while (l0dev_list[i]) { - dl0=l0dev_list[i]; + dl0 = l0dev_list[i]; if (dl0->init) { - (void) dl0->init(); //TODO : forward errors up ? + (void)dl0->init(); // TODO : forward errors up ? } i++; } @@ -83,9 +90,13 @@ diag_l1_init(void) { return 0; } -//diag_l1_end : opposite of diag_l1_init . Non-critical for now -int diag_l1_end(void) { - diag_l1_initdone=0; +// diag_l1_end : opposite of diag_l1_init . +int +diag_l1_end(void) { + diag_l1_initdone = 0; + + DIAG_ATOMIC_DEL(&diag_l1_debug); + return 0; } @@ -95,9 +106,9 @@ int diag_l1_end(void) { */ int diag_l1_open(struct diag_l0_device *dl0d, int l1protocol) { - if (diag_l1_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "diag_l1_open(0x%p, l1 proto=%d\n", FL, - (void *)dl0d, l1protocol); + if (diag_l1_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "diag_l1_open(0x%p, l1 proto=%d\n", FL, (void *)dl0d, + l1protocol); } /* Check h/w supports this l1 protocol */ @@ -109,11 +120,11 @@ diag_l1_open(struct diag_l0_device *dl0d, int l1protocol) { return diag_l0_open(dl0d, l1protocol); } -//diag_l1_close : call the ->close member of the -//specified diag_l0_device. +// diag_l1_close : call the ->close member of the +// specified diag_l0_device. void diag_l1_close(struct diag_l0_device *dl0d) { - if (diag_l1_debug & DIAG_DEBUG_CLOSE) { + if (diag_l1_debug_load() & DIAG_DEBUG_CLOSE) { fprintf(stderr, FLFMT "entering diag_l1_close: dl0d=%p\n", FL, (void *)dl0d); } @@ -123,13 +134,13 @@ diag_l1_close(struct diag_l0_device *dl0d) { return; } -int diag_l1_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { +int +diag_l1_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { /* At the moment, no ioctls are handled at the L1 level, so forward them to L0. */ return diag_l0_ioctl(dl0d, cmd, data); } - /* * Send a load of data * @@ -142,7 +153,8 @@ int diag_l1_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { * Returns 0 on success */ int -diag_l1_send(struct diag_l0_device *dl0d, const char *subinterface, const void *data, size_t len, unsigned int p4) { +diag_l1_send(struct diag_l0_device *dl0d, const char *subinterface, const void *data, + size_t len, unsigned int p4) { int rv = DIAG_ERR_GENERAL; uint32_t l0flags; uint8_t duplexbuf[MAXRBUF]; @@ -153,10 +165,10 @@ diag_l1_send(struct diag_l0_device *dl0d, const char *subinterface, const void * l0flags = diag_l1_getflags(dl0d); - if (diag_l1_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "_send: len=%d P4=%u l0flags=0x%X; ", FL, - (int) len, p4, l0flags); - if (diag_l1_debug & DIAG_DEBUG_DATA) { + if (diag_l1_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "_send: len=%d P4=%u l0flags=0x%X; ", FL, (int)len, + p4, l0flags); + if (diag_l1_debug_load() & DIAG_DEBUG_DATA) { diag_data_dump(stderr, data, len); } fprintf(stderr, "\n"); @@ -169,27 +181,29 @@ diag_l1_send(struct diag_l0_device *dl0d, const char *subinterface, const void * * send the whole message to L0 as one write */ - if ( ((p4 == 0) && ((l0flags & DIAG_L1_HALFDUPLEX) == 0)) || - (l0flags & DIAG_L1_DOESL2FRAME) || (l0flags & DIAG_L1_DOESP4WAIT) || - ((p4==0) && (l0flags & DIAG_L1_BLOCKDUPLEX)) ) { + if (((p4 == 0) && ((l0flags & DIAG_L1_HALFDUPLEX) == 0)) || + (l0flags & DIAG_L1_DOESL2FRAME) || (l0flags & DIAG_L1_DOESP4WAIT) || + ((p4 == 0) && (l0flags & DIAG_L1_BLOCKDUPLEX))) { /* * Send the lot */ rv = diag_l0_send(dl0d, subinterface, data, len); - //optionally remove echos - if ((l0flags & DIAG_L1_BLOCKDUPLEX) && (rv==0)) { - //try to read the same number of sent bytes; timeout=300ms + 1ms/byte - //This is plenty OK for typical 10.4kbps but should be changed - //if ever slow speeds are used. - if (diag_l0_recv(dl0d, NULL, duplexbuf, len, 300+len) != (int) len) { - rv=DIAG_ERR_GENERAL; + // optionally remove echos + if ((l0flags & DIAG_L1_BLOCKDUPLEX) && (rv == 0)) { + // try to read the same number of sent bytes; timeout=300ms + + // 1ms/byte This is plenty OK for typical 10.4kbps but should be + // changed if ever slow speeds are used. + if (diag_l0_recv(dl0d, NULL, duplexbuf, len, 300 + len) != + (int)len) { + rv = DIAG_ERR_GENERAL; } - //compare to sent bytes - if ( memcmp(duplexbuf, data, len) !=0) { - fprintf(stderr,FLFMT "Bus Error: bad half duplex echo!\n", FL); - rv=DIAG_ERR_BUSERROR; + // compare to sent bytes + if (memcmp(duplexbuf, data, len) != 0) { + fprintf(stderr, FLFMT "Bus Error: bad half duplex echo!\n", + FL); + rv = DIAG_ERR_BUSERROR; } } } else { @@ -213,13 +227,15 @@ diag_l1_send(struct diag_l0_device *dl0d, const char *subinterface, const void * c = *dp - 1; /* set it with wrong val. */ if (diag_l0_recv(dl0d, NULL, &c, 1, 200) != 1) { - rv=DIAG_ERR_GENERAL; + rv = DIAG_ERR_GENERAL; break; } if (c != *dp) { if (c == *dp - 1) { - fprintf(stderr,"Half duplex interface not echoing!\n"); + fprintf(stderr, + "Half duplex interface not " + "echoing!\n"); } else { fprintf(stderr, "Bus Error: got 0x%X " @@ -238,63 +254,65 @@ diag_l1_send(struct diag_l0_device *dl0d, const char *subinterface, const void * } } - return rv? diag_iseterr(rv):0; + return rv ? diag_iseterr(rv) : 0; } /* * Get data (blocking, unless timeout is 0) * returns # of bytes read, or <0 if error. - * XXX currently nothing handles the case of L0 returning 0 bytes read. Logically that could - * only happen when requesting n bytes with a timeout of 0; otherwise DIAG_ERR_TIMEOUT will - * generated. + * XXX currently nothing handles the case of L0 returning 0 bytes read. Logically that + * could only happen when requesting n bytes with a timeout of 0; otherwise + * DIAG_ERR_TIMEOUT will generated. */ int -diag_l1_recv(struct diag_l0_device *dl0d, - const char *subinterface, void *data, size_t len, unsigned int timeout) { +diag_l1_recv(struct diag_l0_device *dl0d, const char *subinterface, void *data, size_t len, + unsigned int timeout) { int rv; if (!len) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l1_debug & DIAG_DEBUG_READ) { - fprintf(stderr, FLFMT "_recv request len=%d, timeout=%u;", FL, - (int)len, timeout); + if (diag_l1_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "_recv request len=%d, timeout=%u;", FL, (int)len, + timeout); } if (timeout == 0) { fprintf(stderr, - FLFMT - "Interesting : L1 read with timeout=0. Report this !\n", - FL); + FLFMT "Interesting : L1 read with timeout=0. Report this !\n", FL); } - rv=diag_l0_recv(dl0d, subinterface, data, len, timeout); + rv = diag_l0_recv(dl0d, subinterface, data, len, timeout); if (!rv) { - fprintf(stderr, FLFMT "L0 returns with 0 bytes; returning TIMEOUT instead. Report this !\n", FL); + fprintf(stderr, + FLFMT + "L0 returns with 0 bytes; returning TIMEOUT instead. Report this " + "!\n", + FL); return DIAG_ERR_TIMEOUT; } - if ((rv>0) && - (diag_l1_debug & DIAG_DEBUG_DATA) && (diag_l1_debug & DIAG_DEBUG_READ)) { - fprintf(stderr, "got %d bytes, ",rv); + if ((rv > 0) && (diag_l1_debug_load() & DIAG_DEBUG_DATA) && + (diag_l1_debug_load() & DIAG_DEBUG_READ)) { + fprintf(stderr, "got %d bytes, ", rv); diag_data_dump(stderr, data, (size_t)rv); } - if (diag_l1_debug & DIAG_DEBUG_READ) { + if (diag_l1_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, "\n"); } return rv; } - -//diag_l1_getflags: returns l0 flags -uint32_t diag_l1_getflags(struct diag_l0_device *dl0d) { +// diag_l1_getflags: returns l0 flags +uint32_t +diag_l1_getflags(struct diag_l0_device *dl0d) { return diag_l0_getflags(dl0d); } -//diag_l1_gettype: returns l1proto_mask :supported L1 protos -//of the l0 driver -int diag_l1_gettype(struct diag_l0_device *dl0d) { +// diag_l1_gettype: returns l1proto_mask :supported L1 protos +// of the l0 driver +int +diag_l1_gettype(struct diag_l0_device *dl0d) { return dl0d->dl0->l1proto_mask; } - diff --git a/scantool/diag_l1.h b/scantool/diag_l1.h index 0e5ea870..801a513d 100644 --- a/scantool/diag_l1.h +++ b/scantool/diag_l1.h @@ -29,12 +29,11 @@ * - Layer 1 interface definitions */ -#include "diag.h" //we need this for uint8_t -#include "diag_tty.h" //for structs serial_settings +#include "diag.h" //we need this for uint8_t +#include "diag_tty.h" //for structs serial_settings #include "diag_cfg.h" #include "diag_l0.h" - #if defined(__cplusplus) extern "C" { #endif @@ -54,12 +53,12 @@ extern "C" { * Can be read by higher layers using ..._ioctl(GET_L1_FLAGS) */ - -#define DIAG_L1_SLOW 0x01 /* Supports SLOW (5 baud) Start */ -#define DIAG_L1_FAST 0x02 /* Supports FAST Start */ -#define DIAG_L1_PREFSLOW 0x04 /* Prefers SLOW (5 baud) Start */ -#define DIAG_L1_PREFFAST 0x08 /* Prefers FAST Start */ -#define DIAG_L1_HALFDUPLEX 0x10 /* Physical interface is half duplex, need to remove echos */ +#define DIAG_L1_SLOW 0x01 /* Supports SLOW (5 baud) Start */ +#define DIAG_L1_FAST 0x02 /* Supports FAST Start */ +#define DIAG_L1_PREFSLOW 0x04 /* Prefers SLOW (5 baud) Start */ +#define DIAG_L1_PREFFAST 0x08 /* Prefers FAST Start */ +#define DIAG_L1_HALFDUPLEX \ + 0x10 /* Physical interface is half duplex, need to remove echos */ /* following flags are for semi-intelligent interfaces */ @@ -69,66 +68,66 @@ extern "C" { * presence of headers / checksum is determined by other flags below * - l1_send() ignores P4 inter-byte spacing when forwarding the data to L0 */ -#define DIAG_L1_DOESL2FRAME 0x20 +#define DIAG_L1_DOESL2FRAME 0x20 /* * DOESSLOWINIT * L1/L0 interface does the slowinit stuff, so L2 doesn't need to do complex * handshake. L1 will send the keybytes on the first recv(). (All L1's * read the 0x55 and do the right thing, L2 never sees that) See DIAG_L1_DOESFULLINIT */ -#define DIAG_L1_DOESSLOWINIT 0x40 +#define DIAG_L1_DOESSLOWINIT 0x40 /* * DOESL2CKSUM * L1/L0 interface adds the L2 checksum/CRC on send */ -#define DIAG_L1_DOESL2CKSUM 0x80 +#define DIAG_L1_DOESL2CKSUM 0x80 /* * STRIPSL2CKSUM * L1 strips/checks L2 checksum before sending frame upward */ -#define DIAG_L1_STRIPSL2CKSUM 0x100 +#define DIAG_L1_STRIPSL2CKSUM 0x100 /* * DOESP4WAIT * * interface is semi-intelligent and does the interbyte delay P4 for ISO * (P4 : inter-byte delay for messages from tester (us) to ECU) */ -#define DIAG_L1_DOESP4WAIT 0x200 +#define DIAG_L1_DOESP4WAIT 0x200 -//AUTOSPEED -//interface takes care of setting the baudrate; we check this before -//calling diag_l1_setspeed -#define DIAG_L1_AUTOSPEED 0x400 +// AUTOSPEED +// interface takes care of setting the baudrate; we check this before +// calling diag_l1_setspeed +#define DIAG_L1_AUTOSPEED 0x400 -//NOTTY : specifically for carsim interface. Prevents l2_ioctl -//from calling diag_tty_* -#define DIAG_L1_NOTTY 0x800 +// NOTTY : specifically for carsim interface. Prevents l2_ioctl +// from calling diag_tty_* +#define DIAG_L1_NOTTY 0x800 -//BLOCKDUPLEX -//This tells diag_l1_send() to do half-duplex removal on the whole -//block instead of byte per byte ( if P4=0 ; no interbyte spacing) +// BLOCKDUPLEX +// This tells diag_l1_send() to do half-duplex removal on the whole +// block instead of byte per byte ( if P4=0 ; no interbyte spacing) #define DIAG_L1_BLOCKDUPLEX 0x1000 -//NOHDRS -//this indicates that L1 already stripped the headers from the frame (ELM default behavior) -//but the l0_elm init code enables headers so this is not useful at the moment. -//If NOHDRS, DIAG_L1_DOESL2FRAME must also be set! (otherwise, no hope of splitting messages...) +// NOHDRS +// this indicates that L1 already stripped the headers from the frame (ELM default +// behavior) but the l0_elm init code enables headers so this is not useful at the moment. +// If NOHDRS, DIAG_L1_DOESL2FRAME must also be set! (otherwise, no hope of splitting +// messages...) #define DIAG_L1_NOHDRS 0x2000 -//DOESFULLINIT -//indicates that L0 does the full init, including keybyte stuff. (like ELMs) -//this implies that the initbus ioctl still has to be used. +// DOESFULLINIT +// indicates that L0 does the full init, including keybyte stuff. (like ELMs) +// this implies that the initbus ioctl still has to be used. #define DIAG_L1_DOESFULLINIT 0x4000 -//DATAONLY -//indicates that L0 adds headers + checksums before sending to ECU (like ELMs). +// DATAONLY +// indicates that L0 adds headers + checksums before sending to ECU (like ELMs). #define DIAG_L1_DATAONLY 0x8000 -//DOESKEEPALIVE -//L0 handles any periodic message required by L2/L3. +// DOESKEEPALIVE +// L0 handles any periodic message required by L2/L3. #define DIAG_L1_DOESKEEPALIVE 0x10000 - /* * Layer 0 device types * @@ -138,14 +137,14 @@ extern "C" { * This is a bitmask of what is supported; * used for struct diag_l0 (l1proto_mask) */ -#define DIAG_L1_ISO9141 0x01 /* K line */ -#define DIAG_L1_ISO14230 0x02 /* K line, different inits allowed */ -#define DIAG_L1_J1850_VPW 0x04 /* J1850 interface, 10400 baud, VPW */ -#define DIAG_L1_J1850_PWM 0x08 /* J1850 interface 41600 baud, PWM */ -#define DIAG_L1_CAN 0x10 /* CAN bus */ -#define DIAG_L1_RES1 0x20 /* Reserved */ -#define DIAG_L1_RES2 0x40 /* Reserved */ -#define DIAG_L1_RAW 0x80 /* Raw data interface */ +#define DIAG_L1_ISO9141 0x01 /* K line */ +#define DIAG_L1_ISO14230 0x02 /* K line, different inits allowed */ +#define DIAG_L1_J1850_VPW 0x04 /* J1850 interface, 10400 baud, VPW */ +#define DIAG_L1_J1850_PWM 0x08 /* J1850 interface 41600 baud, PWM */ +#define DIAG_L1_CAN 0x10 /* CAN bus */ +#define DIAG_L1_RES1 0x20 /* Reserved */ +#define DIAG_L1_RES2 0x40 /* Reserved */ +#define DIAG_L1_RAW 0x80 /* Raw data interface */ /* * Number of concurrently supported logical interfaces @@ -161,7 +160,6 @@ extern "C" { */ //#define DIAG_L1_MAXINTF 16 - /* * L2 -> L1 interface * @@ -170,17 +168,17 @@ extern "C" { /* Argument for DIAG_IOCTL_INITBUS */ struct diag_l1_initbus_args { - uint8_t type; /* Init type */ - uint8_t addr; /* ECU (target) address, if iso9141 or 14230 init */ - uint8_t testerid; /* tester address, for 14230 init */ - uint8_t physaddr; //1:physical addressing, 0: func. iso14230 only. - uint8_t kb1, kb2; /* key bytes (return value from L0) */ + uint8_t type; /* Init type */ + uint8_t addr; /* ECU (target) address, if iso9141 or 14230 init */ + uint8_t testerid; /* tester address, for 14230 init */ + uint8_t physaddr; // 1:physical addressing, 0: func. iso14230 only. + uint8_t kb1, kb2; /* key bytes (return value from L0) */ }; -//initbus types: -#define DIAG_L1_INITBUS_NONE 0 /* Not needed */ -#define DIAG_L1_INITBUS_FAST 1 /* Fast init (25ms low, 25ms high) */ -#define DIAG_L1_INITBUS_5BAUD 2 /* 5 baud init */ -#define DIAG_L1_INITBUS_2SLOW 3 /* 2 second low on bus, ISO9141-1989 style ? */ +// initbus types: +#define DIAG_L1_INITBUS_NONE 0 /* Not needed */ +#define DIAG_L1_INITBUS_FAST 1 /* Fast init (25ms low, 25ms high) */ +#define DIAG_L1_INITBUS_5BAUD 2 /* 5 baud init */ +#define DIAG_L1_INITBUS_2SLOW 3 /* 2 second low on bus, ISO9141-1989 style ? */ /********** Public L1 interface **********/ /** Parses through the l0dev_list linked list @@ -194,7 +192,6 @@ int diag_l1_init(void); /** Opposite of diag_l1_init; does nothing for now */ int diag_l1_end(void); - /** Send IOCTL to L1/L0 * @param command : IOCTL #, defined in diag.h * @param data optional, input/output @@ -202,10 +199,9 @@ int diag_l1_end(void); */ int diag_l1_ioctl(struct diag_l0_device *, unsigned cmd, void *data); - /** calls l0 ->open with the specified L1 protocol; -* @return 0 if ok -*/ + * @return 0 if ok + */ int diag_l1_open(struct diag_l0_device *, int L1protocol); /** Calls diag_l0_close as required; always succeeds. */ @@ -215,14 +211,16 @@ void diag_l1_close(struct diag_l0_device *); * @param p4 : inter-byte spacing (ms), if applicable. * @return 0 if ok */ -int diag_l1_send(struct diag_l0_device *, const char *subinterface, const void *data, size_t len, unsigned int p4); +int diag_l1_send(struct diag_l0_device *, const char *subinterface, const void *data, + size_t len, unsigned int p4); /** Receive data. * - * @return # of bytes read, DIAG_ERR_TIMEOUT or \<0 if failed. DIAG_ERR_TIMEOUT is not a hard failure - * since a lot of L2 code uses this to detect end of responses + * @return # of bytes read, DIAG_ERR_TIMEOUT or \<0 if failed. DIAG_ERR_TIMEOUT is not a + * hard failure since a lot of L2 code uses this to detect end of responses */ -int diag_l1_recv(struct diag_l0_device *, const char *subinterface, void *data, size_t len, unsigned int timeout); +int diag_l1_recv(struct diag_l0_device *, const char *subinterface, void *data, size_t len, + unsigned int timeout); /** Get L0/L1 device flags (defined in diag_l1.h) * @return bitmask of L0/L1 flags @@ -236,9 +234,11 @@ int diag_l1_gettype(struct diag_l0_device *); /**********/ -extern int diag_l1_debug; //L1 debug flags (see diag.h) +// L1 debug flags (see diag.h) +void diag_l1_debug_store(int d); +int diag_l1_debug_load(void); #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L1_H_ */ diff --git a/scantool/diag_l2.c b/scantool/diag_l2.c index f42bb97a..5bbaac55 100644 --- a/scantool/diag_l2.c +++ b/scantool/diag_l2.c @@ -25,7 +25,7 @@ * * This sits "under" the L2 per-protocol (such as ISO 14230, SAE J1979) * - understands the protocol format, - * - pads messages as needed, + * - pads messages as needed, * - and sends "tester present" messages at the correct intervals to keep * the link to an ECU alive * @@ -44,25 +44,30 @@ #include "diag_l2.h" #include "utlist.h" - -int diag_l2_debug; - +DIAG_ATOMIC_STATICALLY_DECL_INIT(static diag_atomic_int diag_l2_debug) +void +diag_l2_debug_store(int d) { + diag_atomic_store_int(&diag_l2_debug, d); +} +int +diag_l2_debug_load(void) { + return diag_atomic_load_int(&diag_l2_debug); +} /* struct to manage L2 stuff, used in here only */ static struct { - diag_mtx *connlist_mtx; // mutex for accessing dl2conn_list + diag_mtx connlist_mtx; // mutex for accessing dl2conn_list struct diag_l2_conn *dl2conn_list; // linked-list of current diag_l2_conn-s struct diag_l2_link *dl2l_list; // linked-list of current L2-L0 links bool init_done; -} l2internal = {0}; - +} l2internal = {LOCK_INITIALIZER, NULL, NULL, false}; /** Find an existing L2 link using the specified L0 device. * @return NULL if not found */ static struct diag_l2_link * diag_l2_findlink(struct diag_l0_device *dl0d) { - struct diag_l2_link *dl2l=NULL; + struct diag_l2_link *dl2l = NULL; LL_FOREACH(l2internal.dl2l_list, dl2l) { if (dl2l->l2_dl0d == dl0d) { @@ -80,12 +85,13 @@ diag_l2_findlink(struct diag_l0_device *dl0d) { * Always returns 0 */ -static int diag_l2_rmconn(struct diag_l2_conn *dl2c) { - assert(dl2c !=NULL); +static int +diag_l2_rmconn(struct diag_l2_conn *dl2c) { + assert(dl2c != NULL); - diag_os_lock(l2internal.connlist_mtx); + diag_os_lock(&l2internal.connlist_mtx); LL_DELETE(l2internal.dl2conn_list, dl2c); - diag_os_unlock(l2internal.connlist_mtx); + diag_os_unlock(&l2internal.connlist_mtx); return 0; } @@ -104,16 +110,16 @@ static int diag_l2_rmconn(struct diag_l2_conn *dl2c) { */ void diag_l2_timer(void) { - struct diag_l2_conn *d_l2_conn; + struct diag_l2_conn *d_l2_conn; unsigned long now; - if (!diag_os_trylock(l2internal.connlist_mtx)) { + now = diag_os_getms(); /* XXX probably Not async safe */ + + if (periodic_done() || !diag_os_trylock(&l2internal.connlist_mtx)) { return; } - now=diag_os_getms(); /* XXX probably Not async safe */ - LL_FOREACH(l2internal.dl2conn_list, d_l2_conn) { int expired = 0; @@ -121,24 +127,25 @@ diag_l2_timer(void) { * If in monitor mode, or the connection isn't open, * or L1 does the keepalive, do nothing */ - if (((d_l2_conn->diag_l2_type & DIAG_L2_TYPE_INITMASK) ==DIAG_L2_TYPE_MONINIT) || - (d_l2_conn->diag_l2_state != DIAG_L2_STATE_OPEN) || - (d_l2_conn->diag_link->l1flags & DIAG_L1_DOESKEEPALIVE)) { + if (((d_l2_conn->diag_l2_type & DIAG_L2_TYPE_INITMASK) == + DIAG_L2_TYPE_MONINIT) || + (d_l2_conn->diag_l2_state != DIAG_L2_STATE_OPEN) || + (d_l2_conn->diag_link->l1flags & DIAG_L1_DOESKEEPALIVE)) { continue; } /* Check the send timers vs requested expiry time */ - //we're subtracting unsigned values but since the clock is - //monotonic, the difference will always be >= 0 - expired = ((now - d_l2_conn->tlast) > d_l2_conn->tinterval)? 1:0 ; + // we're subtracting unsigned values but since the clock is + // monotonic, the difference will always be >= 0 + expired = ((now - d_l2_conn->tlast) > d_l2_conn->tinterval) ? 1 : 0; /* If expired, call the timeout routine */ if (expired && d_l2_conn->l2proto->diag_l2_proto_timeout) { d_l2_conn->l2proto->diag_l2_proto_timeout(d_l2_conn); } } - diag_os_unlock(l2internal.connlist_mtx); + diag_os_unlock(&l2internal.connlist_mtx); return; } @@ -159,18 +166,20 @@ diag_l2_addmsg(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { /* * Init called to initialise local structures */ -int diag_l2_init() { +int +diag_l2_init() { if (l2internal.init_done) { return 0; } - if (diag_l2_debug & DIAG_DEBUG_INIT) { + DIAG_ATOMIC_INITSTATIC(&diag_l2_debug); + + if (diag_l2_debug_load() & DIAG_DEBUG_INIT) { fprintf(stderr, FLFMT "entered diag_l2_init\n", FL); } - l2internal.connlist_mtx = diag_os_newmtx(); - assert(l2internal.connlist_mtx != NULL); + diag_os_initstaticmtx(&l2internal.connlist_mtx); l2internal.dl2l_list = NULL; l2internal.dl2conn_list = NULL; @@ -179,9 +188,11 @@ int diag_l2_init() { return 0; } -//diag_l2_end : opposite of diag_l2_init ! -int diag_l2_end() { - diag_os_delmtx(l2internal.connlist_mtx); +// diag_l2_end : opposite of diag_l2_init ! +int +diag_l2_end() { + diag_os_delmtx(&l2internal.connlist_mtx); + DIAG_ATOMIC_DEL(&diag_l2_debug); l2internal.init_done = 0; return 0; } @@ -196,9 +207,8 @@ static int diag_l2_closelink(struct diag_l2_link *dl2l) { assert(dl2l != NULL); - if (diag_l2_debug & DIAG_DEBUG_CLOSE) { - fprintf(stderr, FLFMT "l2_closelink %p called\n", FL, - (void *)dl2l); + if (diag_l2_debug_load() & DIAG_DEBUG_CLOSE) { + fprintf(stderr, FLFMT "l2_closelink %p called\n", FL, (void *)dl2l); } /* Remove from linked-list */ @@ -229,7 +239,7 @@ diag_l2_open(struct diag_l0_device *dl0d, int L1protocol) { int rv; struct diag_l2_link *dl2l; - if (diag_l2_debug & DIAG_DEBUG_OPEN) { + if (diag_l2_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "l2_open %s on %p, L1proto=%d\n", FL, dl0d->dl0->longname, (void *)dl0d, L1protocol); } @@ -238,7 +248,7 @@ diag_l2_open(struct diag_l0_device *dl0d, int L1protocol) { dl2l = diag_l2_findlink(dl0d); if (dl2l) { - if (diag_l2_debug & DIAG_DEBUG_OPEN) { + if (diag_l2_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, "\texisting L2 link \"%s\" found\n", dl2l->l2_dl0d->dl0->shortname); } @@ -254,11 +264,11 @@ diag_l2_open(struct diag_l0_device *dl0d, int L1protocol) { rv = diag_l1_open(dl0d, L1protocol); if (rv) { - return diag_iseterr(rv); //forward error to next level + return diag_iseterr(rv); // forward error to next level } /* Create the L2 link */ - if ((rv=diag_calloc(&dl2l, 1))) { + if ((rv = diag_calloc(&dl2l, 1))) { return diag_iseterr(rv); } @@ -293,34 +303,36 @@ diag_l2_close(struct diag_l0_device *dl0d) { struct diag_l2_conn *d_l2_conn; struct diag_l2_link *dl2l; - if (diag_l2_debug & DIAG_DEBUG_CLOSE) { - fprintf(stderr, FLFMT "Entered diag_l2_close for dl0d=%p;\n", - FL, (void *)dl0d); + if (diag_l2_debug_load() & DIAG_DEBUG_CLOSE) { + fprintf(stderr, FLFMT "Entered diag_l2_close for dl0d=%p;\n", FL, + (void *)dl0d); } - assert(dl0d !=NULL); //crash if it's null. We need to fix these problems. + assert(dl0d != NULL); // crash if it's null. We need to fix these problems. - diag_os_lock(l2internal.connlist_mtx); + diag_os_lock(&l2internal.connlist_mtx); // Check if dl0d is still used by someone in l2internal.dl2conn_list LL_FOREACH(l2internal.dl2conn_list, d_l2_conn) { if (d_l2_conn->diag_link->l2_dl0d == dl0d) { - fprintf(stderr, FLFMT "Not closing dl0d: used by dl2conn %p!\n", FL, - (void *) d_l2_conn); - diag_os_unlock(l2internal.connlist_mtx); - return diag_iseterr(DIAG_ERR_GENERAL); //there's still a dl2conn using it ! + fprintf(stderr, FLFMT "Not closing dl0d: used by dl2conn %p!\n", + FL, (void *)d_l2_conn); + diag_os_unlock(&l2internal.connlist_mtx); + return diag_iseterr(DIAG_ERR_GENERAL); // there's still a dl2conn + // using it ! } } while ((dl2l = diag_l2_findlink(dl0d)) != NULL) { - /* can't just "LL_FOREACH" since we're removing stuff from the list as we go */ - if (diag_l2_debug & DIAG_DEBUG_CLOSE) { - fprintf(stderr, "\tclosing dl2link %p.\n", (void *) dl2l); + /* can't just "LL_FOREACH" since we're removing stuff from the list as we + * go */ + if (diag_l2_debug_load() & DIAG_DEBUG_CLOSE) { + fprintf(stderr, "\tclosing dl2link %p.\n", (void *)dl2l); } - diag_l2_closelink(dl2l); //closelink calls diag_l1_close() as required + diag_l2_closelink(dl2l); // closelink calls diag_l1_close() as required } - diag_os_unlock(l2internal.connlist_mtx); + diag_os_unlock(&l2internal.connlist_mtx); return 0; } @@ -334,22 +346,22 @@ diag_l2_close(struct diag_l0_device *dl0d) { */ struct diag_l2_conn * diag_l2_StartCommunications(struct diag_l0_device *dl0d, int L2protocol, flag_type flags, - unsigned int bitrate, target_type target, source_type source) { - struct diag_l2_conn *d_l2_conn; + unsigned int bitrate, target_type target, source_type source) { + struct diag_l2_conn *d_l2_conn; const struct diag_l2_proto *dl2p; struct diag_l2_link *dl2l; - int i,rv; + int i, rv; - assert(dl0d!=NULL); + assert(dl0d != NULL); - if (diag_l2_debug & DIAG_DEBUG_OPEN) { + if (diag_l2_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "_startCommunications dl0d=%p L2proto %d flags=0x%X " "%ubps target=0x%X src=0x%X\n", - FL, (void *)dl0d, L2protocol, flags, bitrate, - target & 0xff, source & 0xff); + FL, (void *)dl0d, L2protocol, flags, bitrate, target & 0xff, + source & 0xff); } /* there must be a dl2l with the desired dl0d. */ @@ -361,16 +373,18 @@ diag_l2_StartCommunications(struct diag_l0_device *dl0d, int L2protocol, flag_ty /* * Check connection doesn't exist already, if it does, do not reuse ! - * with the current L1/L2 structure, hoping to share one L1 between more than one l2 - * is a bad idea. + * with the current L1/L2 structure, hoping to share one L1 between more than one + * l2 is a bad idea. */ - diag_os_lock(l2internal.connlist_mtx); + diag_os_lock(&l2internal.connlist_mtx); LL_FOREACH(l2internal.dl2conn_list, d_l2_conn) { if (d_l2_conn->diag_link == dl2l) { - fprintf(stderr, "Already an L2 connection with specified dl0-dl2l, cannot reuse !\n"); - diag_os_unlock(l2internal.connlist_mtx); + fprintf(stderr, + "Already an L2 connection with specified dl0-dl2l, cannot " + "reuse !\n"); + diag_os_unlock(&l2internal.connlist_mtx); return diag_pseterr(DIAG_ERR_GENERAL); } } @@ -378,7 +392,7 @@ diag_l2_StartCommunications(struct diag_l0_device *dl0d, int L2protocol, flag_ty /* Create new L2 connection */ rv = diag_calloc(&d_l2_conn, 1); if (rv != 0) { - diag_os_unlock(l2internal.connlist_mtx); + diag_os_unlock(&l2internal.connlist_mtx); return diag_pseterr(rv); } d_l2_conn->diag_link = dl2l; @@ -387,7 +401,7 @@ diag_l2_StartCommunications(struct diag_l0_device *dl0d, int L2protocol, flag_ty d_l2_conn->l2proto = NULL; - for (i=0; l2proto_list[i] ; i++) { + for (i = 0; l2proto_list[i]; i++) { dl2p = l2proto_list[i]; if (dl2p->diag_l2_protocol == L2protocol) { d_l2_conn->l2proto = dl2p; @@ -396,17 +410,15 @@ diag_l2_StartCommunications(struct diag_l0_device *dl0d, int L2protocol, flag_ty } if (d_l2_conn->l2proto == NULL) { - fprintf(stderr, - FLFMT "Protocol %d not installed.\n", FL, L2protocol); + fprintf(stderr, FLFMT "Protocol %d not installed.\n", FL, L2protocol); free(d_l2_conn); - diag_os_unlock(l2internal.connlist_mtx); + diag_os_unlock(&l2internal.connlist_mtx); return diag_pseterr(DIAG_ERR_GENERAL); } - - d_l2_conn->diag_l2_type = flags ; - d_l2_conn->diag_l2_srcaddr = source ; - d_l2_conn->diag_l2_destaddr = target ; + d_l2_conn->diag_l2_type = flags; + d_l2_conn->diag_l2_srcaddr = source; + d_l2_conn->diag_l2_destaddr = target; /* * We are going to assume that the ISO default timing values @@ -423,25 +435,24 @@ diag_l2_StartCommunications(struct diag_l0_device *dl0d, int L2protocol, flag_ty d_l2_conn->diag_l2_p4min = ISO_14230_TIM_MIN_P4; d_l2_conn->diag_l2_p4max = ISO_14230_TIM_MAX_P4; - d_l2_conn->tinterval = (ISO_14230_TIM_MAX_P3 * 2/3); //default keepalive interval. + d_l2_conn->tinterval = (ISO_14230_TIM_MAX_P3 * 2 / 3); // default keepalive + // interval. d_l2_conn->diag_l2_state = DIAG_L2_STATE_CLOSED; /* Now do protocol version of StartCommunications */ - rv = d_l2_conn->l2proto->diag_l2_proto_startcomms(d_l2_conn, - flags, bitrate, target, source); + rv = d_l2_conn->l2proto->diag_l2_proto_startcomms(d_l2_conn, flags, bitrate, + target, source); if (rv < 0) { /* Something went wrong */ - if (diag_l2_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, - FLFMT "protocol startcomms returned %d\n", FL, - rv); + if (diag_l2_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "protocol startcomms returned %d\n", FL, rv); } free(d_l2_conn); - diag_os_unlock(l2internal.connlist_mtx); + diag_os_unlock(&l2internal.connlist_mtx); return diag_pseterr(rv); } @@ -454,15 +465,15 @@ diag_l2_StartCommunications(struct diag_l0_device *dl0d, int L2protocol, flag_ty /* And attach connection info to our main list */ LL_PREPEND(l2internal.dl2conn_list, d_l2_conn); - d_l2_conn->tlast=diag_os_getms(); + d_l2_conn->tlast = diag_os_getms(); d_l2_conn->diag_l2_state = DIAG_L2_STATE_OPEN; - if (diag_l2_debug & DIAG_DEBUG_OPEN) { + if (diag_l2_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "diag_l2_StartComms returns %p\n", FL, (void *)d_l2_conn); } - diag_os_unlock(l2internal.connlist_mtx); + diag_os_unlock(&l2internal.connlist_mtx); return d_l2_conn; } @@ -486,24 +497,23 @@ diag_l2_StopCommunications(struct diag_l2_conn *d_l2_conn) { (void)d_l2_conn->l2proto->diag_l2_proto_stopcomms(d_l2_conn); } - //remove from the main linked list + // remove from the main linked list diag_l2_rmconn(d_l2_conn); - //We assume the protocol-specific _stopcomms() cleared out anything it - //may have alloc'ed. inside the l2 connection struct. + // We assume the protocol-specific _stopcomms() cleared out anything it + // may have alloc'ed. inside the l2 connection struct. // But we might still have some attached messages that - //were never freed, so we need to purge those: + // were never freed, so we need to purge those: if (d_l2_conn->diag_msg != NULL) { diag_freemsg(d_l2_conn->diag_msg); } - //and free() the connection. + // and free() the connection. free(d_l2_conn); return 0; } - /* * Send a message. This is synchronous. * calls the appropriate l2_proto_send() @@ -513,22 +523,20 @@ int diag_l2_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { int rv; - if (diag_l2_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, - FLFMT "diag_l2_send %p msg %p msglen %d called\n", FL, + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "diag_l2_send %p msg %p msglen %d called\n", FL, (void *)d_l2_conn, (void *)msg, msg->len); } /* Call protocol specific send routine */ rv = d_l2_conn->l2proto->diag_l2_proto_send(d_l2_conn, msg); - if (rv==0) { - //update timestamp + if (rv == 0) { + // update timestamp d_l2_conn->tlast = diag_os_getms(); } - - return rv? diag_iseterr(rv):0 ; + return rv ? diag_iseterr(rv) : 0; } /* @@ -540,7 +548,7 @@ struct diag_msg * diag_l2_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval) { struct diag_msg *rxmsg; - if (diag_l2_debug & DIAG_DEBUG_WRITE) { + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { fprintf(stderr, FLFMT "_request dl2c=%p msg=%p called\n", FL, (void *)d_l2_conn, (void *)msg); } @@ -548,21 +556,20 @@ diag_l2_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errva /* Call protocol specific send routine */ rxmsg = d_l2_conn->l2proto->diag_l2_proto_request(d_l2_conn, msg, errval); - if (diag_l2_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "_request returns %p, err %d\n", - FL, (void *)rxmsg, *errval); + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "_request returns %p, err %d\n", FL, (void *)rxmsg, + *errval); } - if (rxmsg==NULL) { + if (rxmsg == NULL) { return diag_pseterr(*errval); } - //update timers + // update timers d_l2_conn->tlast = diag_os_getms(); return rxmsg; } - /* * Recv a message - will end up calling the callback routine with a message * or an error if an error has occurred @@ -574,10 +581,10 @@ diag_l2_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errva */ int diag_l2_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - void (*callback)(void *handle, struct diag_msg *msg), void *handle) { + void (*callback)(void *handle, struct diag_msg *msg), void *handle) { int rv; - if (diag_l2_debug & DIAG_DEBUG_READ) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "diag_l2_recv %p timeout %u called\n", FL, (void *)d_l2_conn, timeout); } @@ -585,10 +592,10 @@ diag_l2_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, /* Call protocol specific recv routine */ rv = d_l2_conn->l2proto->diag_l2_proto_recv(d_l2_conn, timeout, callback, handle); - if (rv==0) { - //update timers if success + if (rv == 0) { + // update timers if success d_l2_conn->tlast = diag_os_getms(); - } else if (diag_l2_debug & DIAG_DEBUG_READ) { + } else if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "diag_l2_recv returns %d\n", FL, rv); } @@ -600,19 +607,20 @@ diag_l2_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, * Unix ioctl() * ret 0 if ok */ -int diag_l2_ioctl(struct diag_l2_conn *d_l2_conn, unsigned int cmd, void *data) { +int +diag_l2_ioctl(struct diag_l2_conn *d_l2_conn, unsigned int cmd, void *data) { struct diag_l0_device *dl0d; int rv = 0; struct diag_l2_data *d; struct diag_l2_link *dl2l; - if (diag_l2_debug & DIAG_DEBUG_IOCTL) { - fprintf(stderr, FLFMT "diag_l2_ioctl %p cmd 0x%X\n", FL, - (void *)d_l2_conn, cmd); + if (diag_l2_debug_load() & DIAG_DEBUG_IOCTL) { + fprintf(stderr, FLFMT "diag_l2_ioctl %p cmd 0x%X\n", FL, (void *)d_l2_conn, + cmd); } dl2l = d_l2_conn->diag_link; - dl0d = dl2l->l2_dl0d ; + dl0d = dl2l->l2_dl0d; switch (cmd) { case DIAG_IOCTL_GET_L1_TYPE: @@ -649,12 +657,12 @@ int diag_l2_ioctl(struct diag_l2_conn *d_l2_conn, unsigned int cmd, void *data) rv = diag_l1_ioctl(dl0d, cmd, data); break; case DIAG_IOCTL_INITBUS: - //fall-through to L1 + // fall-through to L1 default: /* Not implemented by L2 : forward to L1 */ rv = diag_l1_ioctl(dl0d, cmd, data); break; } - return rv? diag_iseterr(rv):0 ; + return rv ? diag_iseterr(rv) : 0; } diff --git a/scantool/diag_l2.h b/scantool/diag_l2.h index 7dd6cab1..35fd840b 100644 --- a/scantool/diag_l2.h +++ b/scantool/diag_l2.h @@ -41,18 +41,17 @@ extern "C" { #endif -//diag_l2_link : elements of the diag_l2_links linked-list. -//An l2 link associates an existing diag_l0_device with -//one L1 proto and L1 flags. +// diag_l2_link : elements of the diag_l2_links linked-list. +// An l2 link associates an existing diag_l0_device with +// one L1 proto and L1 flags. struct diag_l2_link { - struct diag_l0_device *l2_dl0d; /* Link we're using to talk to lower layer */ - int l1proto; /* L1 protocol used; see diag_l1.h*/ + struct diag_l0_device *l2_dl0d; /* Link we're using to talk to lower layer */ + int l1proto; /* L1 protocol used; see diag_l1.h*/ - uint32_t l1flags; /* L1 flags, filled with diag_l1_getflags in diag_l2_open*/ - int l1type; /* L1 type (see diag_l1.h): mask of supported L1 protos. */ - - struct diag_l2_link *next; /* linked list of all connections */ + uint32_t l1flags; /* L1 flags, filled with diag_l1_getflags in diag_l2_open*/ + int l1type; /* L1 type (see diag_l1.h): mask of supported L1 protos. */ + struct diag_l2_link *next; /* linked list of all connections */ }; struct diag_msg; @@ -63,49 +62,50 @@ struct diag_msg; * more than one ECU per L1 link */ struct diag_l2_conn { - enum { - DIAG_L2_STATE_CLOSED, /* Not in use (but not free for anyones use !!) */ - DIAG_L2_STATE_SENTCONREQ, /* Sent connection request (waiting for response/reject) */ - DIAG_L2_STATE_OPEN, /* Up and running; only legal state for sending a keepalive request */ - DIAG_L2_STATE_CLOSING /* sending close request (possibly), waiting for response/timeout */ - } diag_l2_state; /* State: mainly used by the timer code for keepalive msgs.*/ - - - - struct diag_l2_link *diag_link; /* info about L1 connection */ - - //The following two members are used for periodic keep-alive messages. - //tlast is updated when diag_l2_send, _recv, + enum { DIAG_L2_STATE_CLOSED, /* Not in use (but not free for anyones use !!) */ + DIAG_L2_STATE_SENTCONREQ, /* Sent connection request (waiting for + response/reject) */ + DIAG_L2_STATE_OPEN, /* Up and running; only legal state for sending a + keepalive request */ + DIAG_L2_STATE_CLOSING /* sending close request (possibly), waiting for + response/timeout */ + } diag_l2_state; /* State: mainly used by the timer code for keepalive msgs.*/ + + struct diag_l2_link *diag_link; /* info about L1 connection */ + + // The following two members are used for periodic keep-alive messages. + // tlast is updated when diag_l2_send, _recv, // _request, or _startcomm is called succesfully. - unsigned long tlast; // Time of last received || sent data, in ms. - unsigned long tinterval; // How long before expiry (usually set by startcomms() once). Set to -1 for "never" + unsigned long tlast; // Time of last received || sent data, in ms. + unsigned long tinterval; // How long before expiry (usually set by startcomms() + // once). Set to -1 for "never" - const struct diag_l2_proto *l2proto; /* Protocol handler */ + const struct diag_l2_proto *l2proto; /* Protocol handler */ - flag_type diag_l2_type; /* Type info for this L2 connection; */ - //will contain init type (slow/mon/fast/etc) and anything else passed - //in the flag_type flags argument of l2_startcomms. See DIAG_L2_TYPE_* - // defines below. + flag_type diag_l2_type; /* Type info for this L2 connection; */ + // will contain init type (slow/mon/fast/etc) and anything else passed + // in the flag_type flags argument of l2_startcomms. See DIAG_L2_TYPE_* + // defines below. // Message timing values. // See SAE-J1979 for general usage; // See ISO-14230-2, ISO-9141-2, SAE-J1850 for specific values; - uint16_t diag_l2_p1min; - uint16_t diag_l2_p1max; // p1 = byte gap from ECU; - uint16_t diag_l2_p2min; - uint16_t diag_l2_p2max; // p2 = gap from request to response; - uint16_t diag_l2_p2emin; - uint16_t diag_l2_p2emax; // p2 in extended mode (ISO14230 "rspPending"); - uint16_t diag_l2_p3min; - uint16_t diag_l2_p3max; // p3 = gap from end of all responses to new request; - uint16_t diag_l2_p4min; - uint16_t diag_l2_p4max; // p4 = byte gap from tester. + uint16_t diag_l2_p1min; + uint16_t diag_l2_p1max; // p1 = byte gap from ECU; + uint16_t diag_l2_p2min; + uint16_t diag_l2_p2max; // p2 = gap from request to response; + uint16_t diag_l2_p2emin; + uint16_t diag_l2_p2emax; // p2 in extended mode (ISO14230 "rspPending"); + uint16_t diag_l2_p3min; + uint16_t diag_l2_p3max; // p3 = gap from end of all responses to new request; + uint16_t diag_l2_p4min; + uint16_t diag_l2_p4max; // p4 = byte gap from tester. /* Protocol independent data */ - void *diag_l2_proto_data; + void *diag_l2_proto_data; /* Speed we're using (baud) */ - unsigned int diag_l2_speed; + unsigned int diag_l2_speed; /* * Physical ECU address (useful if doing logical addressing @@ -113,10 +113,10 @@ struct diag_l2_conn { * from received messages only - some of this may belong in * protocol specific l2 info not in this general structure. */ - uint8_t diag_l2_physaddr; + uint8_t diag_l2_physaddr; - uint8_t diag_l2_destaddr; /* Dest (ECU) */ - uint8_t diag_l2_srcaddr; /* Source (US) */ + uint8_t diag_l2_destaddr; /* Dest (ECU) */ + uint8_t diag_l2_srcaddr; /* Source (US) */ /* * The following two should be in the protocol specific bit * because they only apply to ISO protocols (move at some time @@ -126,38 +126,37 @@ struct diag_l2_conn { * to handle DIAG_IOCTL_GET_L2_DATA . It could stay in here for * the moment */ - uint8_t diag_l2_kb1; /* KB 1, (ISO stuff really) */ - uint8_t diag_l2_kb2; /* KB 2, (ISO stuff really) */ - + uint8_t diag_l2_kb1; /* KB 1, (ISO stuff really) */ + uint8_t diag_l2_kb2; /* KB 2, (ISO stuff really) */ /* Main linked list of all connections */ struct diag_l2_conn *next; /* Generic receive buffer */ - uint8_t rxbuf[MAXRBUF]; - int rxoffset; + uint8_t rxbuf[MAXRBUF]; + int rxoffset; /* Generic 'msg' holder */ - struct diag_msg *diag_msg; - + struct diag_msg *diag_msg; }; - /* * Default ISO 14230 timing values, ms, used as defaults for L2 timeouts */ -#define ISO_14230_TIM_MIN_P1 0 /* Inter byte timing in ECU response */ -#define ISO_14230_TIM_MAX_P1 20 -#define ISO_14230_TIM_MIN_P2 25 /* Time between end of tester request and start of ECU response */ -#define ISO_14230_TIM_MAX_P2 50 /* or between ECU responses */ -#define ISO_14230_TIM_MIN_P2E 25 /* Extended mode for "rspPending" */ -#define ISO_14230_TIM_MAX_P2E 5000 /* Extended mode for "rspPending" */ -#define ISO_14230_TIM_MIN_P3 55 /* Time between end of ECU response and start of new tester request */ -#define ISO_14230_TIM_MAX_P3 5000 /* or time between end of tester request and start of new request if ECU - doesn't respond */ -#define ISO_14230_TIM_MIN_P4 5 /* Inter byte time in tester request */ -#define ISO_14230_TIM_MAX_P4 20 - +#define ISO_14230_TIM_MIN_P1 0 /* Inter byte timing in ECU response */ +#define ISO_14230_TIM_MAX_P1 20 +#define ISO_14230_TIM_MIN_P2 \ + 25 /* Time between end of tester request and start of ECU response */ +#define ISO_14230_TIM_MAX_P2 50 /* or between ECU responses */ +#define ISO_14230_TIM_MIN_P2E 25 /* Extended mode for "rspPending" */ +#define ISO_14230_TIM_MAX_P2E 5000 /* Extended mode for "rspPending" */ +#define ISO_14230_TIM_MIN_P3 \ + 55 /* Time between end of ECU response and start of new tester request */ +#define ISO_14230_TIM_MAX_P3 \ + 5000 /* or time between end of tester request and start of new request if ECU \ + doesn't respond */ +#define ISO_14230_TIM_MIN_P4 5 /* Inter byte time in tester request */ +#define ISO_14230_TIM_MAX_P4 20 /* * Application Interface @@ -168,19 +167,19 @@ struct diag_l2_conn { * * NOTE, many of these protocols run on each others physical layer, * for instance J1850 runs on J1850/ISO9141/ISO14230 interfaces - */ -#define DIAG_L2_PROT_RAW 0 /* Raw send/receive, ie. L2 pass thru */ -#define DIAG_L2_PROT_ISO9141 1 /* Iso 9141, keywords 08 08 */ -#define DIAG_L2_PROT_NOTUSED 2 /* NOT USED */ -#define DIAG_L2_PROT_ISO14230 3 /* Iso 14230 using appropriate message format */ -#define DIAG_L2_PROT_SAEJ1850 4 /* SAEJ1850 */ -#define DIAG_L2_PROT_CAN 5 /* CAN L2 (is this defined ??) */ -#define DIAG_L2_PROT_VAG 6 /* VAG ISO9141 based protocol */ -#define DIAG_L2_PROT_MB1 7 /* MB protocol 1 */ -#define DIAG_L2_PROT_MB2 8 /* MB protocol 2 */ -#define DIAG_L2_PROT_D2 9 /* Volvo D2 over K-line (kw D3 B0) */ -#define DIAG_L2_PROT_TEST 10 /* Dummy L2 test driver */ -#define DIAG_L2_PROT_MAX 11 /* Maximum number of protocols */ + */ +#define DIAG_L2_PROT_RAW 0 /* Raw send/receive, ie. L2 pass thru */ +#define DIAG_L2_PROT_ISO9141 1 /* Iso 9141, keywords 08 08 */ +#define DIAG_L2_PROT_NOTUSED 2 /* NOT USED */ +#define DIAG_L2_PROT_ISO14230 3 /* Iso 14230 using appropriate message format */ +#define DIAG_L2_PROT_SAEJ1850 4 /* SAEJ1850 */ +#define DIAG_L2_PROT_CAN 5 /* CAN L2 (is this defined ??) */ +#define DIAG_L2_PROT_VAG 6 /* VAG ISO9141 based protocol */ +#define DIAG_L2_PROT_MB1 7 /* MB protocol 1 */ +#define DIAG_L2_PROT_MB2 8 /* MB protocol 2 */ +#define DIAG_L2_PROT_D2 9 /* Volvo D2 over K-line (kw D3 B0) */ +#define DIAG_L2_PROT_TEST 10 /* Dummy L2 test driver */ +#define DIAG_L2_PROT_MAX 11 /* Maximum number of protocols */ /* * l2proto_list : static-allocated list of supported L2 protocols. @@ -200,16 +199,18 @@ extern const struct diag_l2_proto *l2proto_list[]; * "5BAUD" has to be ==0, etc. That's also why we need _INITMASK * "initmode" macros */ -#define DIAG_L2_TYPE_SLOWINIT 0 /* Do 5 Baud init */ -#define DIAG_L2_TYPE_FASTINIT 1 /* Do fast init */ -#define DIAG_L2_TYPE_CARBINIT 2 /* Do CARB init (see ISO14230-2 5.2.4), not implemented. */ -#define DIAG_L2_TYPE_MONINIT 3 /* Don't do any init, just connect to bus */ -#define DIAG_L2_TYPE_INITMASK 0x0F /* Init options mask */ +#define DIAG_L2_TYPE_SLOWINIT 0 /* Do 5 Baud init */ +#define DIAG_L2_TYPE_FASTINIT 1 /* Do fast init */ +#define DIAG_L2_TYPE_CARBINIT \ + 2 /* Do CARB init (see ISO14230-2 5.2.4), not implemented. \ + */ +#define DIAG_L2_TYPE_MONINIT 3 /* Don't do any init, just connect to bus */ +#define DIAG_L2_TYPE_INITMASK 0x0F /* Init options mask */ /* * DIAG_L2_TYPE_FUNCADDR : the address supplied is a functional * address (instead of physical), used for protocols such as ISO14230 */ -#define DIAG_L2_TYPE_FUNCADDR 0x10 +#define DIAG_L2_TYPE_FUNCADDR 0x10 /* * DIAG_L2_TYPE_PHYSCONN: tell protocols that support both functional and physical @@ -225,36 +226,31 @@ extern const struct diag_l2_proto *l2proto_list[]; * * SAE J1978 is the ODB II ScanTool specification document */ -#define DIAG_L2_IDLE_J1978 0x20 +#define DIAG_L2_IDLE_J1978 0x20 /*****/ - - - // Special Timeout for so-called "Smart" interfaces; // Slower than any protocol, give them time to unframe // and checksum the data: #define SMART_TIMEOUT 150 -#define RXTOFFSET 20 //ms to add to some diag_l1_recv calls in L2 code - //In theory this should be 0... It's a band-aid - //hack to allow system to system variations but NEEDS - //to be replaced by something runtime-configurable either - //by the user or some auto-configured feature of the - //scantool (not implemented yet) - - +#define RXTOFFSET \ + 20 // ms to add to some diag_l1_recv calls in L2 code + // In theory this should be 0... It's a band-aid + // hack to allow system to system variations but NEEDS + // to be replaced by something runtime-configurable either + // by the user or some auto-configured feature of the + // scantool (not implemented yet) /* struct diag_l2_data: Used for DIAG_IOCTL_GET_L2_DATA */ -//this isn't used frequently but L3_vag will eventually need it, -//and cmd_diag_probe uses it to report found ECUs. +// this isn't used frequently but L3_vag will eventually need it, +// and cmd_diag_probe uses it to report found ECUs. -struct diag_l2_data { - uint8_t physaddr; /* Physical address of ECU */ - uint8_t kb1; /* Keybyte 0 */ - uint8_t kb2; /* Keybyte 1 */ +struct diag_l2_data { + uint8_t physaddr; /* Physical address of ECU */ + uint8_t kb1; /* Keybyte 0 */ + uint8_t kb2; /* Keybyte 1 */ }; - /* * L2 flags returned from GET_L2_FLAGS * ( for struct diag_l2_proto->diag_l2_flags ) @@ -265,13 +261,12 @@ struct diag_l2_data { * and re-frame the data - this is done by timing windows or by the * protocol itself */ -#define DIAG_L2_FLAG_FRAMED 0x01 - +#define DIAG_L2_FLAG_FRAMED 0x01 /* * L2 does keep alive to ECU */ -#define DIAG_L2_FLAG_KEEPALIVE 0x04 +#define DIAG_L2_FLAG_KEEPALIVE 0x04 /* * L2 adds L2 checksum : ALWAYS !! Either it lets L1 handle it, or does it itself. @@ -286,15 +281,12 @@ struct diag_l2_data { */ #define DIAG_L2_FLAG_CONNECTS_ALWAYS 0x10 - - /* * Internal interface */ /* Add a msg to a L2 connection */ void diag_l2_addmsg(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg); - /* Public functions */ /** Initialize L2 layer @@ -329,8 +321,9 @@ int diag_l2_close(struct diag_l0_device *); * @param source - source (tester) initialisation address * @return a new struct diag_l2_conn for representing the connection */ -struct diag_l2_conn *diag_l2_StartCommunications(struct diag_l0_device *, int L2protocol, - flag_type flags, unsigned int bitrate, target_type target, source_type source ); +struct diag_l2_conn * +diag_l2_StartCommunications(struct diag_l0_device *, int L2protocol, flag_type flags, + unsigned int bitrate, target_type target, source_type source); /** Stop talking to an ECU; * @@ -346,7 +339,7 @@ int diag_l2_StopCommunications(struct diag_l2_conn *); * be ignored, the one specified to StartCommunications * is used for certain L2 protocols * @return 0 on success, <0 on error -*/ + */ int diag_l2_send(struct diag_l2_conn *connection, struct diag_msg *msg); /** Checks if there's anything to receive (blocking). @@ -356,8 +349,7 @@ int diag_l2_send(struct diag_l2_conn *connection, struct diag_msg *msg); * @return 0 on success */ int diag_l2_recv(struct diag_l2_conn *connection, unsigned int timeout, - void (* rcv_call_back)(void *, struct diag_msg *), void *handle ); - + void (*rcv_call_back)(void *, struct diag_msg *), void *handle); /** Send a message, and wait the appropriate time for a response. * @@ -376,8 +368,8 @@ int diag_l2_recv(struct diag_l2_conn *connection, unsigned int timeout, * @return a new msg if successful, or NULL + sets *errval if failed. * */ -struct diag_msg *diag_l2_request(struct diag_l2_conn *connection, struct diag_msg *msg, - int *errval); +struct diag_msg * +diag_l2_request(struct diag_l2_conn *connection, struct diag_msg *msg, int *errval); /** Send IOCTL to L2/L1 * @param command : IOCTL #, defined in diag.h @@ -386,11 +378,12 @@ struct diag_msg *diag_l2_request(struct diag_l2_conn *connection, struct diag_ms */ int diag_l2_ioctl(struct diag_l2_conn *connection, unsigned int cmd, void *data); +void diag_l2_timer(void); /* Regular timer routine */ -void diag_l2_timer(void); /* Regular timer routine */ +void diag_l2_debug_store(int d); +int diag_l2_debug_load(void); -extern int diag_l2_debug; -extern struct diag_l2_conn *global_l2_conn; //TODO : move in globcfg struct +extern struct diag_l2_conn *global_l2_conn; // TODO : move in globcfg struct /** L2 protocol descriptor * @@ -399,29 +392,29 @@ extern struct diag_l2_conn *global_l2_conn; //TODO : move in globcfg struct struct diag_l2_proto { int diag_l2_protocol; const char *shortname; - int diag_l2_flags; //see #defines above + int diag_l2_flags; // see #defines above //_StartCommunications: the l2 proto implementation of this should modify - //the timing parameters in diag_l2_conn if required; by default in - //diag_l2_startcommunications() iso14230 timings are used. - int (*diag_l2_proto_startcomms)(struct diag_l2_conn *, - flag_type, unsigned int bitrate, target_type, source_type); + // the timing parameters in diag_l2_conn if required; by default in + // diag_l2_startcommunications() iso14230 timings are used. + int (*diag_l2_proto_startcomms)(struct diag_l2_conn *, flag_type, + unsigned int bitrate, target_type, source_type); int (*diag_l2_proto_stopcomms)(struct diag_l2_conn *); - //diag_l2_proto_send : returns 0 if ok + // diag_l2_proto_send : returns 0 if ok int (*diag_l2_proto_send)(struct diag_l2_conn *, struct diag_msg *); - //diag_l2_proto_recv: ret 0 if ok - int (*diag_l2_proto_recv)(struct diag_l2_conn *d_l2_conn, - unsigned int timeout, void (*callback)(void *handle, struct diag_msg *msg), - void *handle); - //diag_l2_proto_request : return a new diag_msg if succesful. - struct diag_msg *(*diag_l2_proto_request)(struct diag_l2_conn *, - struct diag_msg *, int *); - //diag_l2_proto_timeout : this is called periodically (interval - //defined in struct diag_l2_conn, usually to send keepalive messages. + // diag_l2_proto_recv: ret 0 if ok + int (*diag_l2_proto_recv)(struct diag_l2_conn *d_l2_conn, unsigned int timeout, + void (*callback)(void *handle, struct diag_msg *msg), + void *handle); + // diag_l2_proto_request : return a new diag_msg if succesful. + struct diag_msg *(*diag_l2_proto_request)(struct diag_l2_conn *, struct diag_msg *, + int *); + // diag_l2_proto_timeout : this is called periodically (interval + // defined in struct diag_l2_conn, usually to send keepalive messages. void (*diag_l2_proto_timeout)(struct diag_l2_conn *); }; #if defined(__cplusplus) } -#endif -#endif /* _DIAG_L2_H_ */ +# endif +#endif /* _DIAG_L2_H_ */ diff --git a/scantool/diag_l2_can.c b/scantool/diag_l2_can.c index b29c43b4..14c2b756 100644 --- a/scantool/diag_l2_can.c +++ b/scantool/diag_l2_can.c @@ -3,13 +3,4 @@ #include "diag_l2_can.h" const struct diag_l2_proto diag_l2_proto_can = { - DIAG_L2_PROT_CAN, - "CAN", - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL -}; + DIAG_L2_PROT_CAN, "CAN", 0, NULL, NULL, NULL, NULL, NULL, NULL}; diff --git a/scantool/diag_l2_can.h b/scantool/diag_l2_can.h index 30f92ea7..dc8b94c3 100644 --- a/scantool/diag_l2_can.h +++ b/scantool/diag_l2_can.h @@ -33,5 +33,5 @@ extern "C" { #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L2_CAN_H_ */ diff --git a/scantool/diag_l2_d2.c b/scantool/diag_l2_d2.c index c3c701ae..ccb4f745 100644 --- a/scantool/diag_l2_d2.c +++ b/scantool/diag_l2_d2.c @@ -61,10 +61,11 @@ with_parity(uint8_t c, enum diag_parity eo) { } for (i = 0; i < 7; i++) { - p ^= c; p <<= 1; + p ^= c; + p <<= 1; } - return((c&0x7f)|(p&0x80)); + return ((c & 0x7f) | (p & 0x80)); } static int @@ -87,22 +88,21 @@ dl2p_d2_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { diag_os_millisleep(d_l2_conn->diag_l2_p3min); - rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, NULL, buf, - msg->len + 3, d_l2_conn->diag_l2_p4min); + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, NULL, buf, msg->len + 3, + d_l2_conn->diag_l2_p4min); - return rv?diag_iseterr(rv):0; + return rv ? diag_iseterr(rv) : 0; } static int dl2p_d2_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - void (*callback)(void *handle, struct diag_msg *msg), - void *handle) { + void (*callback)(void *handle, struct diag_msg *msg), void *handle) { int rv; uint8_t buf[3 + 62 + 1]; struct diag_msg *msg; - rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, NULL, buf, - sizeof(buf), timeout + 100); + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, NULL, buf, sizeof(buf), + timeout + 100); if (rv < 0) { return rv; } @@ -137,8 +137,7 @@ dl2p_d2_request_callback(void *handle, struct diag_msg *in) { } static struct diag_msg * -dl2p_d2_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, - int *errval) { +dl2p_d2_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval) { int rv; struct diag_msg *rmsg; @@ -163,8 +162,8 @@ dl2p_d2_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, } static int -dl2p_d2_startcomms(struct diag_l2_conn *d_l2_conn, flag_type flags, - unsigned int bitrate, target_type target, source_type source) { +dl2p_d2_startcomms(struct diag_l2_conn *d_l2_conn, flag_type flags, unsigned int bitrate, + target_type target, source_type source) { struct diag_serial_settings set; struct diag_l2_d2 *dp; int rv; @@ -172,8 +171,10 @@ dl2p_d2_startcomms(struct diag_l2_conn *d_l2_conn, flag_type flags, uint8_t wm_data[] = {0x82, 0, 0, 0xa1}; struct diag_l1_initbus_args in; - if (!(d_l2_conn->diag_link->l1flags & DIAG_L1_DOESFULLINIT) || !(d_l2_conn->diag_link->l1flags & DIAG_L1_DOESL2CKSUM)) { - fprintf(stderr, "Can't do D2 over K-line on this L0 interface yet, sorry.\n"); + if (!(d_l2_conn->diag_link->l1flags & DIAG_L1_DOESFULLINIT) || + !(d_l2_conn->diag_link->l1flags & DIAG_L1_DOESL2CKSUM)) { + fprintf(stderr, + "Can't do D2 over K-line on this L0 interface yet, sorry.\n"); return diag_iseterr(DIAG_ERR_PROTO_NOTSUPP); } @@ -208,8 +209,7 @@ dl2p_d2_startcomms(struct diag_l2_conn *d_l2_conn, flag_type flags, set.stopbits = diag_stopbits_1; set.parflag = diag_par_n; - if ((rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_SETSPEED, - (void *)&set))) { + if ((rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_SETSPEED, (void *)&set))) { goto err; } @@ -228,7 +228,8 @@ dl2p_d2_startcomms(struct diag_l2_conn *d_l2_conn, flag_type flags, in.type = DIAG_L1_INITBUS_5BAUD; in.addr = with_parity(target, diag_par_o); in.testerid = dp->srcaddr; - in.kb1 = 0; in.kb2 = 0; + in.kb1 = 0; + in.kb2 = 0; rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_INITBUS, &in); if (rv < 0) { goto err; @@ -237,14 +238,18 @@ dl2p_d2_startcomms(struct diag_l2_conn *d_l2_conn, flag_type flags, if (in.kb1 == 0 && in.kb2 == 0) { d_l2_conn->diag_l2_kb1 = 0xd3; d_l2_conn->diag_l2_kb2 = 0xb0; - fprintf(stderr, FLFMT "_startcomms : L0 didn't return keybytes, continuing anyway\n", FL); + fprintf(stderr, + FLFMT + "_startcomms : L0 didn't return keybytes, continuing anyway\n", + FL); } else { d_l2_conn->diag_l2_kb1 = in.kb1; d_l2_conn->diag_l2_kb2 = in.kb2; } if ((d_l2_conn->diag_l2_kb1 != 0xd3) || (d_l2_conn->diag_l2_kb2 != 0xb0)) { - fprintf(stderr, FLFMT "_startcomms : wrong keybytes %02X%02X, expecting D3B0\n", + fprintf(stderr, + FLFMT "_startcomms : wrong keybytes %02X%02X, expecting D3B0\n", FL, d_l2_conn->diag_l2_kb1, d_l2_conn->diag_l2_kb2); rv = DIAG_ERR_WRONGKB; goto err; @@ -261,18 +266,21 @@ dl2p_d2_startcomms(struct diag_l2_conn *d_l2_conn, flag_type flags, static int dl2p_d2_stopcomms(struct diag_l2_conn *pX) { struct diag_msg msg = {0}; - uint8_t data[] = { 0xa0 }; + uint8_t data[] = {0xa0}; int errval = 0; static struct diag_msg *rxmsg; msg.len = 1; - msg.dest = 0; msg.src = 0; /* use default addresses */ + msg.dest = 0; + msg.src = 0; /* use default addresses */ msg.data = data; rxmsg = dl2p_d2_request(pX, &msg, &errval); if (rxmsg == NULL || errval) { - fprintf(stderr, "StopDiagnosticSession request failed, waiting for session to time out.\n"); + fprintf(stderr, + "StopDiagnosticSession request failed, waiting for session to " + "time out.\n"); diag_os_millisleep(5000); } @@ -282,7 +290,7 @@ dl2p_d2_stopcomms(struct diag_l2_conn *pX) { if (pX->diag_l2_proto_data) { free(pX->diag_l2_proto_data); - pX->diag_l2_proto_data=NULL; + pX->diag_l2_proto_data = NULL; } return 0; @@ -291,12 +299,13 @@ dl2p_d2_stopcomms(struct diag_l2_conn *pX) { static void dl2p_d2_timeout(struct diag_l2_conn *d_l2_conn) { struct diag_msg msg = {0}; - uint8_t data[] = { 0xa1 }; + uint8_t data[] = {0xa1}; int errval = 0; static struct diag_msg *rxmsg; msg.len = 1; - msg.dest = 0; msg.src = 0; /* use default addresses */ + msg.dest = 0; + msg.src = 0; /* use default addresses */ msg.data = data; rxmsg = dl2p_d2_request(d_l2_conn, &msg, &errval); @@ -306,14 +315,13 @@ dl2p_d2_timeout(struct diag_l2_conn *d_l2_conn) { } } -const struct diag_l2_proto diag_l2_proto_d2 = { - DIAG_L2_PROT_D2, - "D2", - DIAG_L2_FLAG_FRAMED | DIAG_L2_FLAG_KEEPALIVE, - dl2p_d2_startcomms, - dl2p_d2_stopcomms, - dl2p_d2_send, - dl2p_d2_recv, - dl2p_d2_request, - dl2p_d2_timeout -}; +const struct diag_l2_proto diag_l2_proto_d2 = {DIAG_L2_PROT_D2, + "D2", + DIAG_L2_FLAG_FRAMED | + DIAG_L2_FLAG_KEEPALIVE, + dl2p_d2_startcomms, + dl2p_d2_stopcomms, + dl2p_d2_send, + dl2p_d2_recv, + dl2p_d2_request, + dl2p_d2_timeout}; diff --git a/scantool/diag_l2_iso14230.c b/scantool/diag_l2_iso14230.c index e17935aa..11eaaeba 100644 --- a/scantool/diag_l2_iso14230.c +++ b/scantool/diag_l2_iso14230.c @@ -39,8 +39,6 @@ #include "diag_l2_iso14230.h" /* prototypes for this file */ - - /* * Useful internal routines */ @@ -53,14 +51,13 @@ * only proto_14230_intrecv should use this... */ static int -dl2p_14230_decode(uint8_t *data, int len, - uint8_t *hdrlen, int *datalen, uint8_t *source, uint8_t *dest, - int first_frame) { +dl2p_14230_decode(uint8_t *data, int len, uint8_t *hdrlen, int *datalen, uint8_t *source, + uint8_t *dest, int first_frame) { uint8_t dl; - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "decode len %d, ", FL, len); - diag_data_dump(stderr, data, (size_t) len); + diag_data_dump(stderr, data, (size_t)len); fprintf(stderr, "\n"); } @@ -72,10 +69,8 @@ dl2p_14230_decode(uint8_t *data, int len, case 0xC0: /* Addresses supplied, additional len byte */ if (len < 4) { - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, - FLFMT "decode len short \n", - FL); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "decode len short \n", FL); } return diag_iseterr(DIAG_ERR_INCDATA); } @@ -158,13 +153,14 @@ dl2p_14230_decode(uint8_t *data, int len, return diag_iseterr(DIAG_ERR_BADDATA); } - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "decode hdrlen=%d, datalen=%d, cksum=1\n", - FL, *hdrlen, *datalen); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "decode hdrlen=%d, datalen=%d, cksum=1\n", FL, + *hdrlen, *datalen); } // return "theoretical" frame length, including headers + data + checksum byte. We - // don't complain if the actual len is shorter because sometimes the cksum will be stripped. + // don't complain if the actual len is shorter because sometimes the cksum will be + // stripped. return (*hdrlen + *datalen + 1); /* @@ -212,17 +208,16 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { int rv, l1_doesl2frame, l1flags; unsigned int tout; int state; - struct diag_msg *tmsg, *lastmsg; + struct diag_msg *tmsg, *lastmsg; -#define ST_STATE1 1 /* Start */ -#define ST_STATE2 2 /* Interbyte */ -#define ST_STATE3 3 /* Inter message */ +#define ST_STATE1 1 /* Start */ +#define ST_STATE2 2 /* Interbyte */ +#define ST_STATE3 3 /* Inter message */ dp = (struct diag_l2_14230 *)d_l2_conn->diag_l2_proto_data; - if (diag_l2_debug & DIAG_DEBUG_READ) { - fprintf(stderr, - FLFMT "_int_recv dl2conn=%p offset=0x%X, tout=%u\n", FL, + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "_int_recv dl2conn=%p offset=0x%X, tout=%u\n", FL, (void *)d_l2_conn, dp->rxoffset, timeout); } @@ -249,24 +244,23 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { } } - while (1) { switch (state) { case ST_STATE1: tout = timeout; break; case ST_STATE2: - //State 2 : if we're between bytes of the same message; if we timeout with P2min it's - //probably because the message is ended. + // State 2 : if we're between bytes of the same message; if we + // timeout with P2min it's probably because the message is ended. tout = d_l2_conn->diag_l2_p2min - 2; if (tout < d_l2_conn->diag_l2_p1max) { tout = d_l2_conn->diag_l2_p1max; } break; case ST_STATE3: - //State 3: we timed out during state 2 + // State 3: we timed out during state 2 if (l1_doesl2frame) { - tout = 150; /* Arbitrary, short, value ... */ + tout = 150; /* Arbitrary, short, value ... */ } else { tout = d_l2_conn->diag_l2_p2max; } @@ -274,7 +268,7 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { /* Receive data into the buffer */ - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "before recv, state=%d timeout=%u, rxoffset " @@ -291,13 +285,12 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { } else { rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &dp->rxbuf[dp->rxoffset], - sizeof(dp->rxbuf) - dp->rxoffset, - tout); + sizeof(dp->rxbuf) - dp->rxoffset, tout); } - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "after recv, rv=%d rxoffset=%d\n", - FL, rv, dp->rxoffset); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "after recv, rv=%d rxoffset=%d\n", FL, rv, + dp->rxoffset); } if (rv == DIAG_ERR_TIMEOUT) { @@ -335,13 +328,15 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { diag_l2_addmsg(d_l2_conn, tmsg); if (d_l2_conn->diag_msg == tmsg) { - if ((diag_l2_debug & DIAG_DEBUG_DATA) && (diag_l2_debug & DIAG_DEBUG_PROTO)) { - fprintf(stderr, FLFMT "Copying %u bytes to data: ", + if ((diag_l2_debug_load() & DIAG_DEBUG_DATA) && + (diag_l2_debug_load() & DIAG_DEBUG_PROTO)) { + fprintf(stderr, + FLFMT "Copying %u bytes to data: ", FL, tmsg->len); - diag_data_dump(stderr, tmsg->data, tmsg->len); + diag_data_dump(stderr, tmsg->data, + tmsg->len); fprintf(stderr, "\n"); } - } state = ST_STATE3; continue; @@ -355,7 +350,7 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { if (state == ST_STATE3) { break; } - } //if diag_err_timeout + } // if diag_err_timeout if (rv <= 0) { break; @@ -366,11 +361,10 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { /* This was wrong : some valid 14230 frames can start with 0x00, and * would have their first byte deleted systematically. - * Note, this is still wrong (monitor mode will still drop some valid frames), - * but arguably less so. + * Note, this is still wrong (monitor mode will still drop some valid + * frames), but arguably less so. */ - if (dp->monitor_mode && - (dp->rxoffset && (dp->rxbuf[0] == 0))) { + if (dp->monitor_mode && (dp->rxoffset && (dp->rxbuf[0] == 0))) { /* * We get this when in * monitor mode and there is @@ -378,12 +372,11 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { */ dp->rxoffset--; if (dp->rxoffset) { - memcpy(&dp->rxbuf[0], &dp->rxbuf[1], - (size_t)dp->rxoffset); + memcpy(&dp->rxbuf[0], &dp->rxbuf[1], (size_t)dp->rxoffset); } continue; } - if ( (state == ST_STATE1) || (state == ST_STATE3) ) { + if ((state == ST_STATE1) || (state == ST_STATE3)) { /* * Got some data in state1/3, now we're in a message */ @@ -403,23 +396,21 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { lastmsg = NULL; while (tmsg != NULL) { - int datalen=0; - uint8_t hdrlen=0, source=0, dest=0; - + int datalen = 0; + uint8_t hdrlen = 0, source = 0, dest = 0; - if ((l1flags & DIAG_L1_NOHDRS)==0) { + if ((l1flags & DIAG_L1_NOHDRS) == 0) { dp = (struct diag_l2_14230 *)d_l2_conn->diag_l2_proto_data; - rv = dl2p_14230_decode( tmsg->data, - tmsg->len, - &hdrlen, &datalen, &source, &dest, - dp->first_frame); + rv = dl2p_14230_decode(tmsg->data, tmsg->len, &hdrlen, &datalen, + &source, &dest, dp->first_frame); if (rv <= 0 || rv > 260) { /* decode failure */ return diag_iseterr(rv); } - // check for sufficient data: (rv = expected len = hdrlen + datalen + ckslen) + // check for sufficient data: (rv = expected len = hdrlen + datalen + // + ckslen) if (l1_doesl2frame == 0) { unsigned expected_len = rv; if (l1flags & DIAG_L1_STRIPSL2CKSUM) { @@ -431,14 +422,12 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { } } - - /* * If L1 isnt doing L2 framing then it is possible * we have misframed this message and it is infact * more than one message, so see if we can decode it */ - if ((l1_doesl2frame == 0) && (rv < (int) tmsg->len)) { + if ((l1_doesl2frame == 0) && (rv < (int)tmsg->len)) { /* * This message contains more than one * data frame (because it arrived with @@ -446,13 +435,13 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { * do horrible copy about the data * things .... */ - struct diag_msg *amsg; + struct diag_msg *amsg; amsg = diag_dupsinglemsg(tmsg); if (amsg == NULL) { return diag_iseterr(DIAG_ERR_NOMEM); } - amsg->len = (uint8_t) rv; - tmsg->len -= (uint8_t) rv; + amsg->len = (uint8_t)rv; + tmsg->len -= (uint8_t)rv; tmsg->data += rv; /* Insert new amsg before old msg */ @@ -466,46 +455,42 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { tmsg = amsg; /* Finish processing this one */ } - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "msg %p decode/rejig done rv=%d hdrlen=%u " "datalen=%d src=%02X dst=%02X\n", - FL, (void *)tmsg, rv, hdrlen, datalen, source, - dest); + FL, (void *)tmsg, rv, hdrlen, datalen, source, dest); } tmsg->fmt = DIAG_FMT_FRAMED; - if ((l1flags & DIAG_L1_NOHDRS)==0) { + if ((l1flags & DIAG_L1_NOHDRS) == 0) { if ((tmsg->data[0] & 0xC0) == 0xC0) { tmsg->fmt |= DIAG_FMT_ISO_FUNCADDR; } } - - //if cs wasn't stripped, we check it: + // if cs wasn't stripped, we check it: if ((l1flags & DIAG_L1_STRIPSL2CKSUM) == 0) { - uint8_t calc_sum=diag_cks1(tmsg->data, (tmsg->len)-1); - if (calc_sum != tmsg->data[tmsg->len -1]) { - fprintf(stderr, FLFMT "Bad checksum: needed %02X,got%02X. Data:", - FL, calc_sum, tmsg->data[tmsg->len -1]); + uint8_t calc_sum = diag_cks1(tmsg->data, (tmsg->len) - 1); + if (calc_sum != tmsg->data[tmsg->len - 1]) { + fprintf(stderr, + FLFMT "Bad checksum: needed %02X,got%02X. Data:", + FL, calc_sum, tmsg->data[tmsg->len - 1]); tmsg->fmt |= DIAG_FMT_BADCS; - diag_data_dump(stderr, tmsg->data, tmsg->len -1); + diag_data_dump(stderr, tmsg->data, tmsg->len - 1); fprintf(stderr, "\n"); } /* and remove checksum byte */ tmsg->len--; - } - tmsg->fmt |= DIAG_FMT_CKSUMMED; //checksum was verified + tmsg->fmt |= DIAG_FMT_CKSUMMED; // checksum was verified tmsg->src = source; tmsg->dest = dest; - tmsg->data += hdrlen; /* Skip past header */ - tmsg->len -= hdrlen; /* remove header */ - - + tmsg->data += hdrlen; /* Skip past header */ + tmsg->len -= hdrlen; /* remove header */ dp->first_frame = 0; @@ -515,11 +500,9 @@ dl2p_14230_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { return rv; } - /* External interface */ -static int -dl2p_14230_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg); +static int dl2p_14230_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg); /* * The complex initialisation routine for ISO14230, which supports * 2 types of initialisation (5-BAUD, FAST) and functional @@ -529,8 +512,8 @@ dl2p_14230_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg); * Remember, we have to wait longer on smart L1 interfaces. */ static int -dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, - unsigned int bitrate, target_type target, source_type source) { +dl2p_14230_startcomms(struct diag_l2_conn *d_l2_conn, flag_type flags, + unsigned int bitrate, target_type target, source_type source) { struct diag_l2_14230 *dp; struct diag_msg msg = {0}; uint8_t data[MAXRBUF]; @@ -548,11 +531,11 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, } d_l2_conn->diag_l2_proto_data = (void *)dp; - dp->initype = flags & DIAG_L2_TYPE_INITMASK; //only keep initmode flags + dp->initype = flags & DIAG_L2_TYPE_INITMASK; // only keep initmode flags dp->srcaddr = source; dp->dstaddr = target; - //set iso14230-specific flags according to what we were given + // set iso14230-specific flags according to what we were given if (flags & DIAG_L2_IDLE_J1978) { dp->modeflags |= ISO14230_IDLE_J1978; } @@ -563,9 +546,8 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, dp->first_frame = 0; dp->monitor_mode = 0; - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, - FLFMT "_startcomms flags=0x%X tgt=0x%X src=0x%X\n", FL, + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "_startcomms flags=0x%X tgt=0x%X src=0x%X\n", FL, flags, target, source); } @@ -586,19 +568,19 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, set.parflag = diag_par_n; /* Set the speed*/ - if ((rv=diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_SETSPEED, (void *) &set))) { - free(dp); - d_l2_conn->diag_l2_proto_data=NULL; //delete pointer to dp - return diag_iseterr(rv); + if ((rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_SETSPEED, (void *)&set))) { + free(dp); + d_l2_conn->diag_l2_proto_data = NULL; // delete pointer to dp + return diag_iseterr(rv); } - dp->state = STATE_CONNECTING ; + dp->state = STATE_CONNECTING; /* Flush unread input, then wait for idle bus. */ (void)diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_IFLUSH, NULL); diag_os_millisleep(300); - //inside this switch, we set rv=0 or rv=error before "break;" + // inside this switch, we set rv=0 or rv=error before "break;" switch (dp->initype & DIAG_L2_TYPE_INITMASK) { /* Fast initialisation */ case DIAG_L2_TYPE_FASTINIT: @@ -615,8 +597,8 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, } msg.src = source; msg.dest = target; - msg.len = 1 ; - data[0]= DIAG_KW2K_SI_SCR ; /* startCommunication rqst*/ + msg.len = 1; + data[0] = DIAG_KW2K_SI_SCR; /* startCommunication rqst*/ msg.data = data; /* Do fast init stuff */ @@ -626,9 +608,10 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_INITBUS, &in); // some L0 devices already do the full startcomm transaction: - if ((d_l2_conn->diag_link->l1flags & DIAG_L1_DOESFULLINIT) && (rv==0)) { - //TODO : somehow extract keybyte data for those cases... - //original elm327s have the "atkw" command to get the keybytes, but clones suck. + if ((d_l2_conn->diag_link->l1flags & DIAG_L1_DOESFULLINIT) && (rv == 0)) { + // TODO : somehow extract keybyte data for those cases... + // original elm327s have the "atkw" command to get the keybytes, + // but clones suck. dp->state = STATE_ESTABLISHED; break; } @@ -639,7 +622,7 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, /* Send the prepared message */ if (dl2p_14230_send(d_l2_conn, &msg)) { - rv=DIAG_ERR_GENERAL; + rv = DIAG_ERR_GENERAL; break; } @@ -658,45 +641,47 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, // _int_recv() should have filled d_l2_conn->diag_msg properly. // check if message is OK : if (d_l2_conn->diag_msg->fmt & DIAG_FMT_BADCS) { - rv=DIAG_ERR_BADCSUM; + rv = DIAG_ERR_BADCSUM; break; } switch (d_l2_conn->diag_msg->data[0]) { - case DIAG_KW2K_RC_SCRPR: /* StartComms positive response */ + case DIAG_KW2K_RC_SCRPR: /* StartComms positive response */ d_l2_conn->diag_l2_kb1 = d_l2_conn->diag_msg->data[1]; d_l2_conn->diag_l2_kb2 = d_l2_conn->diag_msg->data[2]; d_l2_conn->diag_l2_physaddr = d_l2_conn->diag_msg->src; - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, - FLFMT "_StartComms Physaddr=0x%X KB1=%02X, KB2=%02X\n", - FL, d_l2_conn->diag_l2_physaddr, d_l2_conn->diag_l2_kb1, d_l2_conn->diag_l2_kb2); + FLFMT + "_StartComms Physaddr=0x%X KB1=%02X, KB2=%02X\n", + FL, d_l2_conn->diag_l2_physaddr, + d_l2_conn->diag_l2_kb1, d_l2_conn->diag_l2_kb2); } - rv=0; - dp->state = STATE_ESTABLISHED ; + rv = 0; + dp->state = STATE_ESTABLISHED; break; case DIAG_KW2K_RC_NR: - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, - FLFMT "_StartComms got neg response\n", FL); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "_StartComms got neg response\n", + FL); } - rv=DIAG_ERR_ECUSAIDNO; + rv = DIAG_ERR_ECUSAIDNO; break; default: - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "_StartComms got unexpected response 0x%X\n", FL, d_l2_conn->diag_msg->data[0]); } - rv=DIAG_ERR_ECUSAIDNO; + rv = DIAG_ERR_ECUSAIDNO; break; - } //switch data[0] + } // switch data[0] // finished with the response message: diag_freemsg(d_l2_conn->diag_msg); d_l2_conn->diag_msg = NULL; - break; //case _FASTINIT + break; // case _FASTINIT /* 5 Baud init */ case DIAG_L2_TYPE_SLOWINIT: @@ -704,9 +689,9 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, in.addr = target; rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_INITBUS, &in); - //some L0 devices handle the full init transaction: - if ((d_l2_conn->diag_link->l1flags & DIAG_L1_DOESFULLINIT) && (rv==0)) { - dp->state = STATE_ESTABLISHED ; + // some L0 devices handle the full init transaction: + if ((d_l2_conn->diag_link->l1flags & DIAG_L1_DOESFULLINIT) && (rv == 0)) { + dp->state = STATE_ESTABLISHED; break; } @@ -715,15 +700,14 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, } /* Mode bytes are in 7-Odd-1, read as 8N1 and ignore parity */ - rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, 0, - cbuf, 2, 100); + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, cbuf, 2, 100); if (rv < 0) { break; } /* ISO14230 uses KB2 of 0x8F */ if (cbuf[1] != 0x8f) { - rv=DIAG_ERR_WRONGKB; + rv = DIAG_ERR_WRONGKB; break; } @@ -732,71 +716,68 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, d_l2_conn->diag_l2_kb1 = cbuf[0] & 0x7f; d_l2_conn->diag_l2_kb2 = cbuf[1]; - if ( (d_l2_conn->diag_link->l1flags - & DIAG_L1_DOESSLOWINIT) == 0) { + if ((d_l2_conn->diag_link->l1flags & DIAG_L1_DOESSLOWINIT) == 0) { /* * Now transmit KB2 inverted */ - cbuf[0] = ~ d_l2_conn->diag_l2_kb2; - rv = diag_l1_send (d_l2_conn->diag_link->l2_dl0d, 0, - cbuf, 1, d_l2_conn->diag_l2_p4min); + cbuf[0] = ~d_l2_conn->diag_l2_kb2; + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, cbuf, 1, + d_l2_conn->diag_l2_p4min); /* * And wait for the address byte inverted */ - //first init cbuf[0] to the wrong value in case l1_recv gets nothing - cbuf[0]= (uint8_t) target; - rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, 0, - cbuf, 1, 350); - - if (cbuf[0] != ((~target) & 0xFF) ) { - fprintf(stderr, FLFMT "_startcomms : addr mismatch %02X!=%02X\n", - FL, cbuf[0], (uint8_t) ~target); - rv=DIAG_ERR_WRONGKB; + // first init cbuf[0] to the wrong value in case l1_recv gets + // nothing + cbuf[0] = (uint8_t)target; + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, cbuf, 1, 350); + + if (cbuf[0] != ((~target) & 0xFF)) { + fprintf(stderr, + FLFMT "_startcomms : addr mismatch %02X!=%02X\n", + FL, cbuf[0], (uint8_t)~target); + rv = DIAG_ERR_WRONGKB; break; } - if (diag_l2_debug & DIAG_DEBUG_INIT) { - fprintf(stderr, - FLFMT "ISO14230 KB1=%02X KB2=%02X\n", - FL, d_l2_conn->diag_l2_kb1, - d_l2_conn->diag_l2_kb2); + if (diag_l2_debug_load() & DIAG_DEBUG_INIT) { + fprintf(stderr, FLFMT "ISO14230 KB1=%02X KB2=%02X\n", FL, + d_l2_conn->diag_l2_kb1, d_l2_conn->diag_l2_kb2); } } - rv=0; - dp->state = STATE_ESTABLISHED ; - break; //case _SLOWINIT + rv = 0; + dp->state = STATE_ESTABLISHED; + break; // case _SLOWINIT case DIAG_L2_TYPE_MONINIT: /* Monitor mode, don't send anything */ dp->first_frame = 1; dp->monitor_mode = 1; - dp->state = STATE_ESTABLISHED ; + dp->state = STATE_ESTABLISHED; rv = 0; break; default: rv = DIAG_ERR_INIT_NOTSUPP; break; - } //end of switch dp->initype - //At this point we just finished the handshake and got KB1 and KB2 + } // end of switch dp->initype + // At this point we just finished the handshake and got KB1 and KB2 if (rv < 0) { free(dp); - d_l2_conn->diag_l2_proto_data=NULL; //delete pointer to dp + d_l2_conn->diag_l2_proto_data = NULL; // delete pointer to dp return diag_iseterr(rv); } // Analyze keybytes and set modeflags properly. See // iso14230 5.2.4.1 & Table 8 - dp->modeflags |= ((d_l2_conn->diag_l2_kb1 & 1)? ISO14230_FMTLEN:0) | - ((d_l2_conn->diag_l2_kb1 & 2)? ISO14230_LENBYTE:0) | - ((d_l2_conn->diag_l2_kb1 & 4)? ISO14230_SHORTHDR:0) | - ((d_l2_conn->diag_l2_kb1 & 8)? ISO14230_LONGHDR:0); - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "new modeflags=0x%04X\n", FL, - dp->modeflags); + dp->modeflags |= ((d_l2_conn->diag_l2_kb1 & 1) ? ISO14230_FMTLEN : 0) | + ((d_l2_conn->diag_l2_kb1 & 2) ? ISO14230_LENBYTE : 0) | + ((d_l2_conn->diag_l2_kb1 & 4) ? ISO14230_SHORTHDR : 0) | + ((d_l2_conn->diag_l2_kb1 & 8) ? ISO14230_LONGHDR : 0); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "new modeflags=0x%04X\n", FL, dp->modeflags); } - //For now, we won't bother with Normal / Extended timings. We don't - //need to unless we use the AccessTimingParameters service (scary) + // For now, we won't bother with Normal / Extended timings. We don't + // need to unless we use the AccessTimingParameters service (scary) /* * Now, we want to remove any rubbish left @@ -808,26 +789,25 @@ dl2p_14230_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, * 5 * p4max (inter byte delay), whichever is larger * a correct value to use */ - wait_time = d_l2_conn->diag_l2_p2max / 2 ; + wait_time = d_l2_conn->diag_l2_p2max / 2; if ((d_l2_conn->diag_l2_p4max * 5) > wait_time) { wait_time = d_l2_conn->diag_l2_p4max * 5; } - while (diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, data, - sizeof(data), wait_time) != DIAG_ERR_TIMEOUT) { + while (diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, data, sizeof(data), + wait_time) != DIAG_ERR_TIMEOUT) { ; } /* And we're done */ - dp->state = STATE_ESTABLISHED ; + dp->state = STATE_ESTABLISHED; return 0; } -//We need this in _stopcomms +// We need this in _stopcomms static struct diag_msg * -dl2p_14230_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, - int *errval); +dl2p_14230_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval); /* _stopcomms: * Send a stopcomms message, and wait for the +ve response, for upto @@ -844,40 +824,43 @@ static int dl2p_14230_stopcomms(struct diag_l2_conn *pX) { struct diag_msg stopmsg = {0}; struct diag_msg *rxmsg; - uint8_t stopreq=DIAG_KW2K_SI_SPR; - int errval=0; + uint8_t stopreq = DIAG_KW2K_SI_SPR; + int errval = 0; char *debugstr; - stopmsg.len=1; - stopmsg.data=&stopreq; - stopmsg.dest=0; - stopmsg.src=0; + stopmsg.len = 1; + stopmsg.data = &stopreq; + stopmsg.dest = 0; + stopmsg.src = 0; - rxmsg=dl2p_14230_request(pX, &stopmsg, &errval); + rxmsg = dl2p_14230_request(pX, &stopmsg, &errval); if (rxmsg != NULL) { - //we got a message; + // we got a message; if (!errval) { - //no error : positive response from ECU. - debugstr="ECU acknowledged request (RC="; + // no error : positive response from ECU. + debugstr = "ECU acknowledged request (RC="; } else { - debugstr="ECU refused request; connection will time-out in 5s.(RC="; + debugstr = + "ECU refused request; connection will time-out in 5s.(RC="; } - errval=rxmsg->data[0]; + errval = rxmsg->data[0]; diag_freemsg(rxmsg); } else { - //no message received... - debugstr="ECU did not respond to request, connection will timeout in 5s. (err="; + // no message received... + debugstr = + "ECU did not respond to request, connection will timeout in 5s. " + "(err="; } - if (diag_l2_debug & DIAG_DEBUG_CLOSE) { + if (diag_l2_debug_load() & DIAG_DEBUG_CLOSE) { fprintf(stderr, FLFMT "_stopcomms: %s0x%02X).\n", FL, debugstr, errval); } - //and free() what startcomms alloc'ed. + // and free() what startcomms alloc'ed. if (pX->diag_l2_proto_data) { free(pX->diag_l2_proto_data); - pX->diag_l2_proto_data=NULL; + pX->diag_l2_proto_data = NULL; } return 0; @@ -899,34 +882,33 @@ dl2p_14230_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { int rv; size_t len; uint8_t buf[MAXRBUF]; - int offset=0; //data payload starts at buf[offset} + int offset = 0; // data payload starts at buf[offset} struct diag_l2_14230 *dp; if (msg->len < 1) { return diag_iseterr(DIAG_ERR_BADLEN); } - if (diag_l2_debug & DIAG_DEBUG_WRITE) { + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { fprintf(stderr, FLFMT "_send: dl2conn=%p msg=%p len=%d\n", FL, (void *)d_l2_conn, (void *)msg, msg->len); } dp = (struct diag_l2_14230 *)d_l2_conn->diag_l2_proto_data; - - //if L1 requires headerless data, send directly : + // if L1 requires headerless data, send directly : if (d_l2_conn->diag_link->l1flags & DIAG_L1_DATAONLY) { - rv = diag_l1_send (d_l2_conn->diag_link->l2_dl0d, NULL, - msg->data, msg->len, d_l2_conn->diag_l2_p4min); - return rv? diag_iseterr(rv):0; + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, NULL, msg->data, msg->len, + d_l2_conn->diag_l2_p4min); + return rv ? diag_iseterr(rv) : 0; } /* Build the new message */ if ((dp->modeflags & ISO14230_LONGHDR) || !(dp->modeflags & ISO14230_SHORTHDR)) { - //we use full headers if they're supported or if we don't have a choice. - //set the "address present" bit - //and functional addressing if applicable + // we use full headers if they're supported or if we don't have a choice. + // set the "address present" bit + // and functional addressing if applicable if (dp->modeflags & ISO14230_FUNCADDR) { buf[0] = 0xC0; } else { @@ -947,25 +929,25 @@ dl2p_14230_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { } offset = 3; } else if (dp->modeflags & ISO14230_SHORTHDR) { - //here, short addressless headers are required. - //basic format byte : 0 - buf[0]=0; - offset = 1 ; + // here, short addressless headers are required. + // basic format byte : 0 + buf[0] = 0; + offset = 1; } - - - if ((dp->modeflags & ISO14230_FMTLEN)|| !(dp->modeflags & ISO14230_LENBYTE)) { - //if ECU supports length in format byte, or doesn't support extra len byte + if ((dp->modeflags & ISO14230_FMTLEN) || !(dp->modeflags & ISO14230_LENBYTE)) { + // if ECU supports length in format byte, or doesn't support extra len byte if (msg->len < 64) { buf[0] |= msg->len; } else { - //len >=64, can we use a length byte ? + // len >=64, can we use a length byte ? if (dp->modeflags & ISO14230_LENBYTE) { buf[offset] = msg->len; offset += 1; } else { - fprintf(stderr, FLFMT "can't send >64 byte msgs to this ECU !\n", FL); + fprintf(stderr, + FLFMT "can't send >64 byte msgs to this ECU !\n", + FL); return diag_iseterr(DIAG_ERR_BADLEN); } } @@ -977,15 +959,15 @@ dl2p_14230_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { memcpy(&buf[offset], msg->data, msg->len); - len = msg->len + offset; /* data + hdr */ + len = msg->len + offset; /* data + hdr */ if ((d_l2_conn->diag_link->l1flags & DIAG_L1_DOESL2CKSUM) == 0) { /* We must add checksum, which is sum of bytes */ buf[len] = diag_cks1(buf, len); - len++; /* + checksum */ + len++; /* + checksum */ } - if ((diag_l2_debug & DIAG_DEBUG_WRITE) && (diag_l2_debug & DIAG_DEBUG_DATA)) { + if (diag_l2_debug_load() & (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) { fprintf(stderr, FLFMT "_send: ", FL); diag_data_dump(stderr, buf, len); fprintf(stderr, "\n"); @@ -996,10 +978,10 @@ dl2p_14230_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { diag_os_millisleep(d_l2_conn->diag_l2_p3min); } - rv = diag_l1_send (d_l2_conn->diag_link->l2_dl0d, NULL, - buf, len, d_l2_conn->diag_l2_p4min); + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, NULL, buf, len, + d_l2_conn->diag_l2_p4min); - return rv? diag_iseterr(rv):0; + return rv ? diag_iseterr(rv) : 0; } /* @@ -1017,8 +999,7 @@ dl2p_14230_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { */ static int dl2p_14230_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - void (*callback)(void *handle, struct diag_msg *msg), - void *handle) { + void (*callback)(void *handle, struct diag_msg *msg), void *handle) { int rv; /* Call internal routine */ @@ -1028,10 +1009,10 @@ dl2p_14230_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, return rv; } - if (diag_l2_debug & DIAG_DEBUG_READ) { - fprintf(stderr, FLFMT "_int_recv : handle=%p timeout=%u\n", FL, - handle, timeout); //%pcallback! we won't try to - // printf the callback pointer. + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "_int_recv : handle=%p timeout=%u\n", FL, handle, + timeout); //%pcallback! we won't try to + // printf the callback pointer. } /* @@ -1045,26 +1026,25 @@ dl2p_14230_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, diag_freemsg(d_l2_conn->diag_msg); d_l2_conn->diag_msg = NULL; - if (diag_l2_debug & DIAG_DEBUG_READ) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "_recv callback completed\n", FL); } return 0; } -//iso14230 diag_l2_proto_request. See diag_l2.h -//This handles busyRepeatRequest and RspPending negative responses. -//return NULL if failed, or a newly alloced diag_msg if succesful. -//Caller must free that diag_msg. -//Sends using diag_l2_send() in order to have the timestamps updated +// iso14230 diag_l2_proto_request. See diag_l2.h +// This handles busyRepeatRequest and RspPending negative responses. +// return NULL if failed, or a newly alloced diag_msg if succesful. +// Caller must free that diag_msg. +// Sends using diag_l2_send() in order to have the timestamps updated static struct diag_msg * -dl2p_14230_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, - int *errval) { +dl2p_14230_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval) { int rv; struct diag_msg *rmsg = NULL; - int retries=3; //if we get a BusyRepeatRequest response. + int retries = 3; // if we get a BusyRepeatRequest response. - *errval=0; + *errval = 0; rv = diag_l2_send(d_l2_conn, msg); if (rv < 0) { @@ -1075,8 +1055,7 @@ dl2p_14230_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, while (1) { /* do read only if no messages pending */ if (!d_l2_conn->diag_msg) { - rv = dl2p_14230_int_recv(d_l2_conn, - d_l2_conn->diag_l2_p2max + 10); + rv = dl2p_14230_int_recv(d_l2_conn, d_l2_conn->diag_l2_p2max + 10); if (rv < 0) { *errval = DIAG_ERR_TIMEOUT; @@ -1114,8 +1093,12 @@ dl2p_14230_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, if (retries > 0) { rv = diag_l2_send(d_l2_conn, msg); } else { - rv=DIAG_ERR_GENERAL; - fprintf(stderr, FLFMT "got too many BusyRepeatRequest responses!\n", FL); + rv = DIAG_ERR_GENERAL; + fprintf(stderr, + FLFMT + "got too many BusyRepeatRequest " + "responses!\n", + FL); } retries--; @@ -1124,11 +1107,9 @@ dl2p_14230_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, *errval = rv; return diag_pseterr(rv); } - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, - FLFMT - "got BusyRepeatRequest: retrying...\n", - FL); + FLFMT "got BusyRepeatRequest: retrying...\n", FL); } continue; @@ -1139,10 +1120,8 @@ dl2p_14230_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, * Msg is a requestCorrectlyRcvd-RspPending * so do read again */ - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, - FLFMT "got RspPending: retrying...\n", - FL); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "got RspPending: retrying...\n", FL); } /* reattach the rest of the chain, in case the good response @@ -1154,9 +1133,9 @@ dl2p_14230_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, continue; } /* Some other type of error */ - *errval= DIAG_ERR_ECUSAIDNO; + *errval = DIAG_ERR_ECUSAIDNO; break; - } //while 1 + } // while 1 /* Return the message to user, who is responsible for freeing it */ return rmsg; } @@ -1171,22 +1150,15 @@ dl2p_14230_timeout(struct diag_l2_conn *d_l2_conn) { struct diag_msg msg = {0}; uint8_t data[256]; unsigned int timeout; - int debug_l2_orig=diag_l2_debug; //save debug flags; disable them for this procedure - int debug_l1_orig=diag_l1_debug; - int debug_l0_orig=diag_l0_debug; dp = (struct diag_l2_14230 *)d_l2_conn->diag_l2_proto_data; /* XXX fprintf not async-signal-safe */ - if (diag_l2_debug & DIAG_DEBUG_TIMER) { - fprintf(stderr, FLFMT "\ntimeout impending for dl2c=%pd\n", - FL, (void *)d_l2_conn); + if (diag_l2_debug_load() & DIAG_DEBUG_TIMER) { + fprintf(stderr, FLFMT "\ntimeout impending for dl2c=%pd\n", FL, + (void *)d_l2_conn); } - diag_l2_debug=0; //disable - diag_l1_debug=0; - diag_l0_debug=0; - msg.data = data; /* Prepare the "keepalive" message */ @@ -1198,8 +1170,8 @@ dl2p_14230_timeout(struct diag_l2_conn *d_l2_conn) { } else { /* Idle using ISO "Tester Present" message */ msg.len = 1; - msg.dest = 0; /* Use default */ - msg.src = 0; /* Use default */ + msg.dest = 0; /* Use default */ + msg.src = 0; /* Use default */ data[0] = DIAG_KW2K_SI_TP; } @@ -1224,10 +1196,6 @@ dl2p_14230_timeout(struct diag_l2_conn *d_l2_conn) { } } (void)diag_l2_recv(d_l2_conn, timeout, NULL, NULL); - diag_l2_debug=debug_l2_orig; //restore debug flags - diag_l1_debug=debug_l1_orig; - diag_l0_debug=debug_l0_orig; - } const struct diag_l2_proto diag_l2_proto_iso14230 = { DIAG_L2_PROT_ISO14230, @@ -1238,5 +1206,4 @@ const struct diag_l2_proto diag_l2_proto_iso14230 = { dl2p_14230_send, dl2p_14230_recv, dl2p_14230_request, - dl2p_14230_timeout -}; + dl2p_14230_timeout}; diff --git a/scantool/diag_l2_iso14230.h b/scantool/diag_l2_iso14230.h index 5c74cb7a..33a61d24 100644 --- a/scantool/diag_l2_iso14230.h +++ b/scantool/diag_l2_iso14230.h @@ -35,26 +35,26 @@ * ISO 14230 specific data */ struct diag_l2_14230 { - uint8_t initype; /* init type : FAST/SLOW/CARB */ + uint8_t initype; /* init type : FAST/SLOW/CARB */ - uint8_t srcaddr; /* Src address used */ - uint8_t dstaddr; /* Dest address used (for connect) */ - int modeflags; /* 14230-specific Flags; see below */ + uint8_t srcaddr; /* Src address used */ + uint8_t dstaddr; /* Dest address used (for connect) */ + int modeflags; /* 14230-specific Flags; see below */ - enum { - STATE_CLOSED=0, /* Established comms */ - STATE_CONNECTING=1, /* Connecting */ - STATE_ESTABLISHED=2, /* Established */ + enum { STATE_CLOSED = 0, /* Established comms */ + STATE_CONNECTING = 1, /* Connecting */ + STATE_ESTABLISHED = 2, /* Established */ } state; - bool first_frame; /* First frame flag, used mainly for - monitor mode when we need to find - out whether we see a CARB or normal - init */ - bool monitor_mode; /* if set, expect possible spurious 0x00 bytes caused by fastinit break */ + bool first_frame; /* First frame flag, used mainly for + monitor mode when we need to find + out whether we see a CARB or normal + init */ + bool monitor_mode; /* if set, expect possible spurious 0x00 bytes caused by + fastinit break */ - uint8_t rxbuf[MAXRBUF]; /* Receive buffer, for building message in */ - int rxoffset; /* Offset to write into buffer */ + uint8_t rxbuf[MAXRBUF]; /* Receive buffer, for building message in */ + int rxoffset; /* Offset to write into buffer */ }; // ******* flags for ->modeflags : @@ -65,36 +65,33 @@ struct diag_l2_14230 { // By default we send fully addressed headers (iso14230 5.2.4.1) #define ISO14230_SHORTHDR 0x01 -//ISO14230_LONGHDR : if set, we can send headers with the address bytes. +// ISO14230_LONGHDR : if set, we can send headers with the address bytes. // Set according to the keybytes. If this and SHORTHDR are set, we // send addressless headers by default. #define ISO14230_LONGHDR 0x2 -//ISO14230_LENBYTE: If set, tell the iso14230 code to always use messages +// ISO14230_LENBYTE: If set, tell the iso14230 code to always use messages // with a length byte. This is primarily for SSF14230 - the Swedish vehicle // implementation of ISO14230, but is set if required by the StartComms keybytes. -//If FMTLEN and LENBYTE are set, then we choose the most adequate. +// If FMTLEN and LENBYTE are set, then we choose the most adequate. #define ISO14230_LENBYTE 0x4 -//ISO14230_FMTLEN: if set, we can send headers with the length encoded in +// ISO14230_FMTLEN: if set, we can send headers with the length encoded in // the format byte. (iso14230) #define ISO14230_FMTLEN 0x8 -//ISO14230_FUNCADDR : if set, functional addressing (instead of phys) is used. +// ISO14230_FUNCADDR : if set, functional addressing (instead of phys) is used. #define ISO14230_FUNCADDR 0x10 -//ISO14230_IDLE_J1978 : use SID 1 PID 0 keep-alive messages instead of the normal -//TesterPresent SID. +// ISO14230_IDLE_J1978 : use SID 1 PID 0 keep-alive messages instead of the normal +// TesterPresent SID. #define ISO14230_IDLE_J1978 0x20 - - - #if defined(__cplusplus) extern "C" { #endif #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L2_ISO14230_H_ */ diff --git a/scantool/diag_l2_iso9141.c b/scantool/diag_l2_iso9141.c index f5279a62..e083159a 100644 --- a/scantool/diag_l2_iso9141.c +++ b/scantool/diag_l2_iso9141.c @@ -43,8 +43,6 @@ #include "diag_l2_iso9141.h" /* prototypes for this file */ - - /* * This implements the handshaking process between Tester and ECU. * It is used to wake up an ECU and get its KeyBytes. @@ -86,8 +84,8 @@ dl2p_iso9141_wakeupECU(struct diag_l2_conn *d_l2_conn) { } if (d_l2_conn->diag_link->l1flags & DIAG_L1_DOESFULLINIT) { - d_l2_conn->diag_l2_kb1=0x08; - d_l2_conn->diag_l2_kb2=0x08; //possibly not true, but who cares. + d_l2_conn->diag_l2_kb1 = 0x08; + d_l2_conn->diag_l2_kb2 = 0x08; // possibly not true, but who cares. d_l2_conn->diag_l2_p2min = 25; return 0; } @@ -95,19 +93,19 @@ dl2p_iso9141_wakeupECU(struct diag_l2_conn *d_l2_conn) { // The L1 device has read the 0x55, and reset the previous speed. // Receive the first KeyByte: - rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, 0, &kb1, 1, W2max+RXTOFFSET); + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &kb1, 1, W2max + RXTOFFSET); if (rv < 0) { return diag_iseterr(DIAG_ERR_WRONGKB); } // Receive the second KeyByte: - rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, 0, &kb2, 1, W3max+RXTOFFSET); + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &kb2, 1, W3max + RXTOFFSET); if (rv < 0) { return diag_iseterr(DIAG_ERR_WRONGKB); } // Check keybytes, these can be 0x08 0x08 or 0x94 0x94: - if ( (kb1 != kb2) || ( (kb1 != 0x08) && (kb1 != 0x94) ) ) { + if ((kb1 != kb2) || ((kb1 != 0x08) && (kb1 != 0x94))) { fprintf(stderr, FLFMT "Wrong Keybytes: got %02X %02X\n", FL, kb1, kb2); return diag_iseterr(DIAG_ERR_WRONGKB); } @@ -126,27 +124,25 @@ dl2p_iso9141_wakeupECU(struct diag_l2_conn *d_l2_conn) { // Now send inverted KeyByte2, and receive inverted address // (unless L1 deals with this): - if ( (d_l2_conn->diag_link->l1flags - & DIAG_L1_DOESSLOWINIT) == 0) { - //Wait W4min: + if ((d_l2_conn->diag_link->l1flags & DIAG_L1_DOESSLOWINIT) == 0) { + // Wait W4min: diag_os_millisleep(W4min); - //Send inverted kb2: - inv_kb2 = (uint8_t) ~kb2; - rv = diag_l1_send (d_l2_conn->diag_link->l2_dl0d, 0, - &inv_kb2, 1, 0); + // Send inverted kb2: + inv_kb2 = (uint8_t)~kb2; + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, &inv_kb2, 1, 0); if (rv < 0) { return diag_iseterr(rv); } // Wait for the address byte inverted: // XXX I added RXTOFFSET as a band-aid fix for systems, like - //mine, that don't receive ~addr with only W4max. See #define - //NOTE : l2_iso14230 uses a huge 350ms timeout for this!! - rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, 0, - &inv_address, 1, W4max + RXTOFFSET); + // mine, that don't receive ~addr with only W4max. See #define + // NOTE : l2_iso14230 uses a huge 350ms timeout for this!! + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &inv_address, 1, + W4max + RXTOFFSET); if (rv < 0) { - if (diag_l2_debug & DIAG_DEBUG_OPEN) { + if (diag_l2_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "wakeupECU(dl2conn %p) did not get " @@ -157,42 +153,39 @@ dl2p_iso9141_wakeupECU(struct diag_l2_conn *d_l2_conn) { } // Check the received inverted address: - if ( inv_address != ((~address) & 0xff)) { + if (inv_address != ((~address) & 0xff)) { fprintf(stderr, - FLFMT "wakeupECU(dl2conn %p) addr mismatch: 0x%02X != 0x%02X\n", - FL, (void *)d_l2_conn, inv_address, ~address); + FLFMT + "wakeupECU(dl2conn %p) addr mismatch: 0x%02X != 0x%02X\n", + FL, (void *)d_l2_conn, inv_address, ~address); return diag_iseterr(DIAG_ERR_BADDATA); } } - //Success! Handshaking done. + // Success! Handshaking done. - if (diag_l2_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, - FLFMT "_wakeupECU dl2con=%p kb1=0x%02X kb2=0x%02X\n", - FL, (void *)d_l2_conn, kb1, kb2); + if (diag_l2_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "_wakeupECU dl2con=%p kb1=0x%02X kb2=0x%02X\n", FL, + (void *)d_l2_conn, kb1, kb2); } return 0; } - /* * This implements the start of a new protocol session. * It wakes up an ECU if not in monitor mode. */ static int -dl2p_iso9141_startcomms(struct diag_l2_conn *d_l2_conn, - flag_type flags, unsigned int bitrate, - target_type target, source_type source) { +dl2p_iso9141_startcomms(struct diag_l2_conn *d_l2_conn, flag_type flags, + unsigned int bitrate, target_type target, source_type source) { int rv; struct diag_serial_settings set; struct diag_l2_iso9141 *dp; - if (diag_l2_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, - FLFMT "_startcomms conn %p %ubps tgt=0x%X src=0x%X\n", - FL, (void *)d_l2_conn, bitrate, target, source); + if (diag_l2_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "_startcomms conn %p %ubps tgt=0x%X src=0x%X\n", FL, + (void *)d_l2_conn, bitrate, target, source); } rv = diag_calloc(&dp, 1); @@ -222,28 +215,27 @@ dl2p_iso9141_startcomms(struct diag_l2_conn *d_l2_conn, if ((rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_SETSPEED, &set))) { free(dp); - d_l2_conn->diag_l2_proto_data=NULL; + d_l2_conn->diag_l2_proto_data = NULL; return diag_iseterr(rv); } // Initialize ECU (unless if in monitor mode): switch (flags & DIAG_L2_TYPE_INITMASK) { - case DIAG_L2_TYPE_MONINIT: - rv = 0; - break; - case DIAG_L2_TYPE_SLOWINIT: - rv = dl2p_iso9141_wakeupECU(d_l2_conn); - break; - default: - //CARB and FASTINIT are not in iso9141. - rv = DIAG_ERR_INIT_NOTSUPP; - break; + case DIAG_L2_TYPE_MONINIT: + rv = 0; + break; + case DIAG_L2_TYPE_SLOWINIT: + rv = dl2p_iso9141_wakeupECU(d_l2_conn); + break; + default: + // CARB and FASTINIT are not in iso9141. + rv = DIAG_ERR_INIT_NOTSUPP; + break; } - if (rv) { free(dp); - d_l2_conn->diag_l2_proto_data=NULL; + d_l2_conn->diag_l2_proto_data = NULL; return diag_iseterr(rv); } @@ -252,7 +244,6 @@ dl2p_iso9141_startcomms(struct diag_l2_conn *d_l2_conn, return 0; } - /* * Free session-specific allocated data. * ISO9141 doesn't have a StopCommunication mechanism like iso14230, @@ -266,13 +257,12 @@ dl2p_iso9141_stopcomms(struct diag_l2_conn *d_l2_conn) { if (dp) { free(dp); } - d_l2_conn->diag_l2_proto_data=NULL; + d_l2_conn->diag_l2_proto_data = NULL; - //Always OK for now. + // Always OK for now. return 0; } - /* * This implements the interpretation of a response message. * With ISO9141, the data length will depend on the @@ -284,32 +274,32 @@ dl2p_iso9141_stopcomms(struct diag_l2_conn *d_l2_conn) { * Should only really be used by the _int_recv function. */ static int -dl2p_iso9141_decode(uint8_t *data, int len, - uint8_t *hdrlen, int *datalen, uint8_t *source, uint8_t *dest) { +dl2p_iso9141_decode(uint8_t *data, int len, uint8_t *hdrlen, int *datalen, uint8_t *source, + uint8_t *dest) { - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "decode len %d: ", FL, len); - diag_data_dump(stderr,data, len); + diag_data_dump(stderr, data, len); fprintf(stderr, "\n"); } - //Check header bytes: + // Check header bytes: if (data[0] != 0x48 || data[1] != 0x6B) { return diag_iseterr(DIAG_ERR_BADDATA); } - //verify minimal length + // verify minimal length if (len - OHLEN_ISO9141 > 0) { *datalen = len - OHLEN_ISO9141; } else { - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "decode len short \n", FL); } return diag_iseterr(DIAG_ERR_INCDATA); } - //Set header length (always the same): + // Set header length (always the same): *hdrlen = OHLEN_ISO9141 - 1; // Set Source and Destination addresses: @@ -320,9 +310,9 @@ dl2p_iso9141_decode(uint8_t *data, int len, *source = data[2]; // Originating ECU; } - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "decode total len = %d, datalen = %d\n", - FL, len, *datalen); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "decode total len = %d, datalen = %d\n", FL, len, + *datalen); } return OHLEN_ISO9141 + *datalen; @@ -341,9 +331,9 @@ dl2p_iso9141_decode(uint8_t *data, int len, * in theory it could be P2min + (8 / baudrate) but there is no * harm in using P2max. * - * XXX Dilemma. To properly split messages, do we trust our timing VS iso9141 P2min/max requirements? - * Do we try to find valid headers + checksum and filter out bad frames ? - * Do we let L3_saej1979 try and DJ the framing through L2 ? + * XXX Dilemma. To properly split messages, do we trust our timing VS iso9141 P2min/max + * requirements? Do we try to find valid headers + checksum and filter out bad frames ? Do + * we let L3_saej1979 try and DJ the framing through L2 ? */ int dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { @@ -357,9 +347,8 @@ dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { #define ST_STATE2 2 // In frame - wait for more bytes. #define ST_STATE3 3 // End of frame - wait for more frames. - if (diag_l2_debug & DIAG_DEBUG_READ) { - fprintf(stderr, FLFMT "_int_recv offset 0x%X\n", FL, - d_l2_conn->rxoffset); + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "_int_recv offset 0x%X\n", FL, d_l2_conn->rxoffset); } dp = (struct diag_l2_iso9141 *)d_l2_conn->diag_l2_proto_data; @@ -390,34 +379,34 @@ dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { state = ST_STATE1; while (1) { switch (state) { - case ST_STATE1: - // Ready for first byte, use timeout - // specified by user. - tout = timeout; - break; + case ST_STATE1: + // Ready for first byte, use timeout + // specified by user. + tout = timeout; + break; - case ST_STATE2: - // Inter-byte timeout within a frame. - // ISO says p1max is the maximum, but in fact - // we give ourselves up to p2min minus a little bit. - tout = d_l2_conn->diag_l2_p2min - 2; - if (tout < d_l2_conn->diag_l2_p1max) { - tout = d_l2_conn->diag_l2_p1max; - } - break; + case ST_STATE2: + // Inter-byte timeout within a frame. + // ISO says p1max is the maximum, but in fact + // we give ourselves up to p2min minus a little bit. + tout = d_l2_conn->diag_l2_p2min - 2; + if (tout < d_l2_conn->diag_l2_p1max) { + tout = d_l2_conn->diag_l2_p1max; + } + break; - case ST_STATE3: - // This is the timeout waiting for any more - // responses from the ECU. ISO says min is p2max - // but we'll use p3min. - // Aditionaly, for "smart" interfaces, we expand - // the timeout to let them process the data. - //TODO: maybe set tout=p3min + margin ? - tout = d_l2_conn->diag_l2_p3min; - if (l1_doesl2frame) { - tout += SMART_TIMEOUT; - } - break; + case ST_STATE3: + // This is the timeout waiting for any more + // responses from the ECU. ISO says min is p2max + // but we'll use p3min. + // Aditionaly, for "smart" interfaces, we expand + // the timeout to let them process the data. + // TODO: maybe set tout=p3min + margin ? + tout = d_l2_conn->diag_l2_p3min; + if (l1_doesl2frame) { + tout += SMART_TIMEOUT; + } + break; } // If L0/L1 does L2 framing, we get full frames, so we don't @@ -425,7 +414,7 @@ dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { if ((state == ST_STATE2) && l1_doesl2frame) { rv = DIAG_ERR_TIMEOUT; } else if (dp->rxoffset == MAXLEN_ISO9141) { - rv = DIAG_ERR_TIMEOUT; //we got a full frame already ! + rv = DIAG_ERR_TIMEOUT; // we got a full frame already ! } else { // Receive data into the buffer: rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, @@ -436,62 +425,61 @@ dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { // Timeout = end of message or end of responses. if (rv == DIAG_ERR_TIMEOUT) { switch (state) { - case ST_STATE1: - // If we got 0 bytes on the 1st read, - // just return the timeout error. - if (dp->rxoffset == 0) { - break; - } - - // Otherwise try to read more bytes into - // this message. - state = ST_STATE2; - continue; + case ST_STATE1: + // If we got 0 bytes on the 1st read, + // just return the timeout error. + if (dp->rxoffset == 0) { break; + } - case ST_STATE2: - // End of that message, maybe more to come; - // Copy data into a message. - tmsg = diag_allocmsg((size_t)dp->rxoffset); - if (tmsg == NULL) { - return diag_iseterr( - DIAG_ERR_NOMEM); - } - memcpy(tmsg->data, dp->rxbuf, - (size_t)dp->rxoffset); - tmsg->rxtime = diag_os_getms(); - - if (diag_l2_debug & DIAG_DEBUG_READ) { - fprintf(stderr, "l2_iso9141_recv: "); - diag_data_dump(stderr, dp->rxbuf, (size_t)dp->rxoffset); - fprintf(stderr, "\n"); - } - - dp->rxoffset = 0; - - // Add received message to response list: - diag_l2_addmsg(d_l2_conn, tmsg); - - // Finished this one, get more: - state = ST_STATE3; - continue; - break; + // Otherwise try to read more bytes into + // this message. + state = ST_STATE2; + continue; + break; - case ST_STATE3: - /* - * No more messages, but we did get one - */ - rv = d_l2_conn->diag_msg->len; - break; - default: - break; - } //switch (state) + case ST_STATE2: + // End of that message, maybe more to come; + // Copy data into a message. + tmsg = diag_allocmsg((size_t)dp->rxoffset); + if (tmsg == NULL) { + return diag_iseterr(DIAG_ERR_NOMEM); + } + memcpy(tmsg->data, dp->rxbuf, (size_t)dp->rxoffset); + tmsg->rxtime = diag_os_getms(); + + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, "l2_iso9141_recv: "); + diag_data_dump(stderr, dp->rxbuf, + (size_t)dp->rxoffset); + fprintf(stderr, "\n"); + } + + dp->rxoffset = 0; + + // Add received message to response list: + diag_l2_addmsg(d_l2_conn, tmsg); + + // Finished this one, get more: + state = ST_STATE3; + continue; + break; + + case ST_STATE3: + /* + * No more messages, but we did get one + */ + rv = d_l2_conn->diag_msg->len; + break; + default: + break; + } // switch (state) // end of all response messages: if (state == ST_STATE3) { break; } - } //if diag_err_timeout + } // if diag_err_timeout // Other reception errors. if (rv <= 0 || rv > 255) { @@ -500,7 +488,7 @@ dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { // Data received OK. // Add length to offset. - dp->rxoffset += (uint8_t) rv; + dp->rxoffset += (uint8_t)rv; // This is where some tweaking might be needed if // we are in monitor mode... but not yet. @@ -510,7 +498,7 @@ dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { state = ST_STATE2; } - }//end while (read cycle). + } // end while (read cycle). // Now walk through the response message list, // and strip off their headers and checksums @@ -524,14 +512,14 @@ dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { while (tmsg) { int datalen; - uint8_t hdrlen=0, source=0, dest=0; + uint8_t hdrlen = 0, source = 0, dest = 0; dp = (struct diag_l2_iso9141 *)d_l2_conn->diag_l2_proto_data; - if ((l1flags & DIAG_L1_NOHDRS)==0) { + if ((l1flags & DIAG_L1_NOHDRS) == 0) { // Parse message structure, if headers are present - rv = dl2p_iso9141_decode( tmsg->data, - tmsg->len, &hdrlen, &datalen, &source, &dest); + rv = dl2p_iso9141_decode(tmsg->data, tmsg->len, &hdrlen, &datalen, + &source, &dest); if (rv < 0 || rv > 255) { // decode failure! @@ -539,26 +527,30 @@ dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { } } else if (!l1_doesl2frame) { // Absent headers, and no framing -> illegal ! - fprintf(stderr, "Warning : insane L1flags (l2frame && nohdrs ?)\n"); + fprintf(stderr, + "Warning : insane L1flags (l2frame && nohdrs " + "?)\n"); return diag_iseterr(DIAG_ERR_GENERAL); } // Process L2 framing, if L1 doesn't do it. if (l1_doesl2frame == 0) { - //we'll have to assume we have only a single message, since at the L1 level - //it's impossible to guess the message length. But, if we got more than MAXLEN_ISO9141 bytes, - //(not allowed by standard), we try splitting the message (assuming the first message had the maximum - //length). It's the best that can be done at this level. + // we'll have to assume we have only a single message, since at the + // L1 level it's impossible to guess the message length. But, if we + // got more than MAXLEN_ISO9141 bytes, (not allowed by standard), + // we + // try splitting the message (assuming the first message had the + // maximum length). It's the best that can be done at this level. if (rv > MAXLEN_ISO9141) { - struct diag_msg *amsg; + struct diag_msg *amsg; amsg = diag_dupsinglemsg(tmsg); if (amsg == NULL) { return diag_iseterr(DIAG_ERR_NOMEM); } - amsg->len = (uint8_t) MAXLEN_ISO9141; - tmsg->len -= (uint8_t) MAXLEN_ISO9141; + amsg->len = (uint8_t)MAXLEN_ISO9141; + tmsg->len -= (uint8_t)MAXLEN_ISO9141; tmsg->data += MAXLEN_ISO9141; /* Insert new amsg before old msg */ @@ -571,27 +563,30 @@ dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { tmsg = amsg; /* Finish processing this one */ } - } // If L1 doesn't strip the checksum byte, verify it: if ((l1flags & DIAG_L1_STRIPSL2CKSUM) == 0) { uint8_t rx_cs = tmsg->data[tmsg->len - 1]; if (rx_cs != diag_cks1(tmsg->data, tmsg->len - 1)) { - fprintf(stderr, FLFMT "Checksum error in received message!\n", FL); + fprintf(stderr, + FLFMT "Checksum error in received message!\n", FL); tmsg->fmt |= DIAG_FMT_BADCS; } else { tmsg->fmt &= ~DIAG_FMT_BADCS; - tmsg->fmt |= DIAG_FMT_FRAMED ; //if the checksum fits, it means we framed things properly. + tmsg->fmt |= DIAG_FMT_FRAMED; // if the checksum fits, it + // means we framed things + // properly. } // "Remove" the checksum byte: tmsg->len--; } else { - tmsg->fmt |= DIAG_FMT_FRAMED ; //if L1 stripped the checksum, it was probably valid ? + tmsg->fmt |= DIAG_FMT_FRAMED; // if L1 stripped the checksum, it + // was probably valid ? } - //if the headers aren't stripped by L1 already: - if ((l1flags & DIAG_L1_NOHDRS)==0) { + // if the headers aren't stripped by L1 already: + if ((l1flags & DIAG_L1_NOHDRS) == 0) { // Set source address: tmsg->src = source; // Set destination address: @@ -602,31 +597,28 @@ dl2p_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { tmsg->len -= (OHLEN_ISO9141 - 1); } - // Message done. Flag it up: tmsg->fmt |= DIAG_FMT_CKSUMMED; // Prepare to decode next message: lastmsg = tmsg; tmsg = tmsg->next; - } //while tmsg + } // while tmsg return 0; } - - //_recv : timeout is fed directly to _int_recv and should be long enough -//to guarantee we receive at least one byte. (P2Max should do the trick) -//ret 0 if ok +// to guarantee we receive at least one byte. (P2Max should do the trick) +// ret 0 if ok static int dl2p_iso9141_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - void (*callback)(void *handle, struct diag_msg *msg), void *handle) { + void (*callback)(void *handle, struct diag_msg *msg), void *handle) { int rv; rv = dl2p_iso9141_int_recv(d_l2_conn, timeout); - if ((rv >= 0) && (d_l2_conn->diag_msg !=NULL)) { - if (diag_l2_debug & DIAG_DEBUG_READ) { + if ((rv >= 0) && (d_l2_conn->diag_msg != NULL)) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "_recv : handle=%p\n", FL, handle); //%pcallback! we won't try to // printf the callback pointer. @@ -643,7 +635,7 @@ dl2p_iso9141_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, d_l2_conn->diag_msg = NULL; } - return (rv<0)? diag_iseterr(rv):0 ; + return (rv < 0) ? diag_iseterr(rv) : 0; } /* @@ -663,14 +655,18 @@ dl2p_iso9141_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { dp = d_l2_conn->diag_l2_proto_data; - if (diag_l2_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "_send dl2c=%p msg=%p\n", FL, - (void *)d_l2_conn, (void *)msg); + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "_send dl2c=%p msg=%p\n", FL, (void *)d_l2_conn, + (void *)msg); } - // Check if the payload plus the overhead (and checksum) exceed protocol packet size: + // Check if the payload plus the overhead (and checksum) exceed protocol packet + // size: if (msg->len + OHLEN_ISO9141 > MAXLEN_ISO9141) { - fprintf(stderr, FLFMT "send: Message payload exceeds maximum allowed by protocol!\n", FL); + fprintf(stderr, + FLFMT + "send: Message payload exceeds maximum allowed by protocol!\n", + FL); return diag_iseterr(DIAG_ERR_BADLEN); } @@ -687,16 +683,16 @@ dl2p_iso9141_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { offset = 0; - //if L1 requires headerless data, send directly : + // if L1 requires headerless data, send directly : if (d_l2_conn->diag_link->l1flags & DIAG_L1_DATAONLY) { - rv = diag_l1_send (d_l2_conn->diag_link->l2_dl0d, NULL, - msg->data, msg->len, d_l2_conn->diag_l2_p4min); - return rv? diag_iseterr(rv):0; + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, NULL, msg->data, msg->len, + d_l2_conn->diag_l2_p4min); + return rv ? diag_iseterr(rv) : 0; } /* add ISO9141-2 header */ - buf[offset++] = 0x68; //defined by spec; - buf[offset++] = 0x6A; //defined by spec; + buf[offset++] = 0x68; // defined by spec; + buf[offset++] = 0x6A; // defined by spec; buf[offset++] = dp->srcaddr; // Now copy in data @@ -705,29 +701,26 @@ dl2p_iso9141_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { // If the interface doesn't do ISO9141-2 checksum, add it in: if ((d_l2_conn->diag_link->l1flags & DIAG_L1_DOESL2CKSUM) == 0) { - uint8_t curoff = (uint8_t) offset; + uint8_t curoff = (uint8_t)offset; buf[offset++] = diag_cks1(buf, curoff); } - if (diag_l2_debug & DIAG_DEBUG_WRITE) { + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { fprintf(stderr, "l2_iso9141_send: "); diag_data_dump(stderr, buf, (size_t)offset); fprintf(stderr, "\n"); } // Send it over the L1 link: - rv = diag_l1_send (d_l2_conn->diag_link->l2_dl0d, NULL, - buf, (size_t)offset, d_l2_conn->diag_l2_p4min); - + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, NULL, buf, (size_t)offset, + d_l2_conn->diag_l2_p4min); - return rv? diag_iseterr(rv):0; + return rv ? diag_iseterr(rv) : 0; } - //_request: ret a new message if ok; NULL if failed static struct diag_msg * -dl2p_iso9141_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, - int *errval) { +dl2p_iso9141_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval) { int rv; struct diag_msg *rmsg = NULL; @@ -752,14 +745,12 @@ dl2p_iso9141_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, return rmsg; } -const struct diag_l2_proto diag_l2_proto_iso9141 = { - DIAG_L2_PROT_ISO9141, - "ISO9141", - DIAG_L2_FLAG_FRAMED, - dl2p_iso9141_startcomms, - dl2p_iso9141_stopcomms, - dl2p_iso9141_send, - dl2p_iso9141_recv, - dl2p_iso9141_request, - NULL -}; +const struct diag_l2_proto diag_l2_proto_iso9141 = {DIAG_L2_PROT_ISO9141, + "ISO9141", + DIAG_L2_FLAG_FRAMED, + dl2p_iso9141_startcomms, + dl2p_iso9141_stopcomms, + dl2p_iso9141_send, + dl2p_iso9141_recv, + dl2p_iso9141_request, + NULL}; diff --git a/scantool/diag_l2_iso9141.h b/scantool/diag_l2_iso9141.h index 7ce39064..8cd38984 100644 --- a/scantool/diag_l2_iso9141.h +++ b/scantool/diag_l2_iso9141.h @@ -48,14 +48,14 @@ extern "C" { #define MAXLEN_ISO9141 (OHLEN_ISO9141 + 7) // Communication Initialization Timings: -#define W0min 2 // w0 = bus high prior to address byte; -#define W1min 60 // w1 = gap from address byte to synch pattern; +#define W0min 2 // w0 = bus high prior to address byte; +#define W1min 60 // w1 = gap from address byte to synch pattern; #define W1max 300 -#define W2min 5 // w2 = gap from synch pattern to keybyte 1; +#define W2min 5 // w2 = gap from synch pattern to keybyte 1; #define W2max 20 -#define W3min 0 // w3 = gap from keybyte 1 to keybyte 2; +#define W3min 0 // w3 = gap from keybyte 1 to keybyte 2; #define W3max 20 -#define W4min 25 // w4 = gap from keybyte 2 and inversion from tester; +#define W4min 25 // w4 = gap from keybyte 2 and inversion from tester; #define W4max 50 #define W5min 300 // w5 = guard time before retransmitting address byte; @@ -63,35 +63,30 @@ extern "C" { * ISO9141 specific data */ struct diag_l2_iso9141 { - uint8_t srcaddr; // Src address used, normally 0xF1 (tester) - uint8_t target; // Target address used, normally 0x33 (ISO9141) + uint8_t srcaddr; // Src address used, normally 0xF1 (tester) + uint8_t target; // Target address used, normally 0x33 (ISO9141) // These should be only in specific protocol structs, but // someone put them in the generic L2 struct, and there seem to be - //a lot of protocols that expect them to be there... :( -// uint8_t kb1; // key Byte 1 -// uint8_t kb2; // key Byte 2 + // a lot of protocols that expect them to be there... :( + // uint8_t kb1; // key Byte 1 + // uint8_t kb2; // key Byte 2 uint8_t rxbuf[MAXLEN_ISO9141]; // Receive buffer, for building message in. uint8_t rxoffset; - enum { - STATE_CLOSED=0, - STATE_CONNECTING=1, - STATE_ESTABLISHED=2, + enum { STATE_CLOSED = 0, + STATE_CONNECTING = 1, + STATE_ESTABLISHED = 2, } state; - }; - - /* Public Interface */ - +/* Public Interface */ // TODO: why does diag_l2_vag.c call this... int diag_l2_proto_iso9141_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout); - #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L2_ISO9141_H_ */ diff --git a/scantool/diag_l2_mb1.c b/scantool/diag_l2_mb1.c index 5c26b25b..e3965f4e 100644 --- a/scantool/diag_l2_mb1.c +++ b/scantool/diag_l2_mb1.c @@ -27,7 +27,6 @@ * TODO : */ - #include #include "diag.h" @@ -37,20 +36,14 @@ #include "diag_l1.h" #include "diag_l2.h" -#include "diag_l2_mb1.h" /* prototypes for this file */ +#include "diag_l2_mb1.h" /* prototypes for this file */ +static int dl2p_mb1_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, + uint8_t *data, int len); static int -dl2p_mb1_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - uint8_t *data, int len); - - -static int -dl2p_mb1_startcomms( struct diag_l2_conn *d_l2_conn, -UNUSED(flag_type flags), -unsigned int bitrate, -target_type target, -UNUSED(source_type source)) { +dl2p_mb1_startcomms(struct diag_l2_conn *d_l2_conn, UNUSED(flag_type flags), + unsigned int bitrate, target_type target, UNUSED(source_type source)) { struct diag_l1_initbus_args in; uint8_t cbuf[2]; int rv; @@ -58,9 +51,8 @@ UNUSED(source_type source)) { uint8_t rxbuf[MAXRBUF]; struct diag_serial_settings set; - if (diag_l2_debug & DIAG_DEBUG_INIT) { - fprintf(stderr, FLFMT "startcomms conn %p\n", FL, - (void *)d_l2_conn); + if (diag_l2_debug_load() & DIAG_DEBUG_INIT) { + fprintf(stderr, FLFMT "startcomms conn %p\n", FL, (void *)d_l2_conn); } /* @@ -79,7 +71,7 @@ UNUSED(source_type source)) { set.parflag = diag_par_n; /* Set the speed as shown */ - rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_SETSPEED, (void *) &set); + rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_SETSPEED, (void *)&set); if (rv < 0) { return diag_iseterr(rv); } @@ -102,20 +94,18 @@ UNUSED(source_type source)) { * L0 code should have set correct baud rate now etc * Now read keybytes, ignoring parity */ - rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, 0, - cbuf, 1, 100); + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, cbuf, 1, 100); if (rv < 0) { return diag_iseterr(rv); } - rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, 0, - &cbuf[1], 1, 100); + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &cbuf[1], 1, 100); if (rv < 0) { return diag_iseterr(rv); } - if (diag_l2_debug & DIAG_DEBUG_INIT) { - fprintf(stderr, FLFMT "startcomms conn %p got kb 0x%X 0x%X\n", - FL, (void *)d_l2_conn, cbuf[0], cbuf[1]); + if (diag_l2_debug_load() & DIAG_DEBUG_INIT) { + fprintf(stderr, FLFMT "startcomms conn %p got kb 0x%X 0x%X\n", FL, + (void *)d_l2_conn, cbuf[0], cbuf[1]); } /* @@ -140,7 +130,7 @@ UNUSED(source_type source)) { * Now we probably get a message back that we don't want * particularly that tells us the ecu part num, h/w and s/w versions */ - (void) dl2p_mb1_int_recv(d_l2_conn, 1000, rxbuf, sizeof(rxbuf)); + (void)dl2p_mb1_int_recv(d_l2_conn, 1000, rxbuf, sizeof(rxbuf)); return diag_iseterr(rv); } @@ -163,7 +153,7 @@ dl2p_mb1_decode(uint8_t *data, int len, int *msglen) { uint16_t cksum; int i; - if (diag_l2_debug & DIAG_DEBUG_READ) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "decode len %d", FL, len); for (i = 0; i < len; i++) { fprintf(stderr, " 0x%X", data[i] & 0xff); @@ -185,19 +175,17 @@ dl2p_mb1_decode(uint8_t *data, int len, int *msglen) { for (i = 0, cksum = 0; i < len - 2; i++) { cksum += data[i]; } - if (data[len-2] != (cksum &0xff)) { - if (diag_l2_debug & DIAG_DEBUG_READ) { - fprintf(stderr, - FLFMT "recv cksum 0x%02X 0x%02X, wanted 0x%X\n", + if (data[len - 2] != (cksum & 0xff)) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "recv cksum 0x%02X 0x%02X, wanted 0x%X\n", FL, data[len - 1] & 0xff, data[len - 2] & 0xff, cksum & 0xffff); } return diag_iseterr(DIAG_ERR_BADCSUM); } - if (data[len-1] != ((cksum>>8) & 0xff)) { - if (diag_l2_debug & DIAG_DEBUG_READ) { - fprintf(stderr, - FLFMT "recv cksum 0x%02X 0x%02X, wanted 0x%X\n", + if (data[len - 1] != ((cksum >> 8) & 0xff)) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "recv cksum 0x%02X 0x%02X, wanted 0x%X\n", FL, data[len - 1] & 0xff, data[len - 2] & 0xff, cksum & 0xffff); } @@ -211,8 +199,8 @@ dl2p_mb1_decode(uint8_t *data, int len, int *msglen) { * returns the data length of the packet received */ static int -dl2p_mb1_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - uint8_t *data, int len) { +dl2p_mb1_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, uint8_t *data, + int len) { int rxoffset, rv; unsigned int tout; int msglen; @@ -222,8 +210,8 @@ dl2p_mb1_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, tout = timeout; msglen = 0; readlen = 3; - while ( (rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, 0, - &data[rxoffset], readlen, tout)) > 0) { + while ((rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &data[rxoffset], + readlen, tout)) > 0) { rxoffset += rv; tout = 100; @@ -254,29 +242,27 @@ dl2p_mb1_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, return rxoffset; } - /* * Read data, attempts to get complete set of responses * */ static int dl2p_mb1_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - void (*callback)(void *handle, struct diag_msg *msg), void *handle) { - uint8_t rxbuf[MAXRBUF]; + void (*callback)(void *handle, struct diag_msg *msg), void *handle) { + uint8_t rxbuf[MAXRBUF]; int rv; struct diag_msg *msg; - rv = dl2p_mb1_int_recv(d_l2_conn, timeout, rxbuf, - sizeof(rxbuf)); + rv = dl2p_mb1_int_recv(d_l2_conn, timeout, rxbuf, sizeof(rxbuf)); if (rv < 0 || rv > (255 + 4)) { return diag_iseterr(DIAG_ERR_GENERAL); } - if (diag_l2_debug & DIAG_DEBUG_READ) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "recv conn %p got %d byte message\n", FL, (void *)d_l2_conn, rv); //%pcallback! we won't try to - //printf the callback pointer. + // printf the callback pointer. } if (rv < 5) { /* Bad, minimum message is 5 bytes */ @@ -290,10 +276,10 @@ dl2p_mb1_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, if (msg == NULL) { return diag_iseterr(DIAG_ERR_NOMEM); } - msg->data[0] = rxbuf[1]; /* Command */ - memcpy(&msg->data[1], &rxbuf[3], (size_t)(rv - 3)); /* Data */ + msg->data[0] = rxbuf[1]; /* Command */ + memcpy(&msg->data[1], &rxbuf[3], (size_t)(rv - 3)); /* Data */ msg->rxtime = diag_os_getms(); - msg->fmt = DIAG_FMT_FRAMED ; + msg->fmt = DIAG_FMT_FRAMED; /* * Call user callback routine @@ -305,7 +291,7 @@ dl2p_mb1_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, /* No longer needed */ diag_freemsg(msg); - if (diag_l2_debug & DIAG_DEBUG_READ) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "recv() callback completed\n", FL); } @@ -324,7 +310,7 @@ dl2p_mb1_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { uint16_t cksum; unsigned i; - if (diag_l2_debug & DIAG_DEBUG_WRITE) { + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { fprintf(stderr, FLFMT "diag_l2_send %p, msg %p called\n", FL, (void *)d_l2_conn, (void *)msg); } @@ -341,20 +327,19 @@ dl2p_mb1_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { } txbuf[0] = d_l2_conn->diag_l2_destaddr; - txbuf[1] = msg->data[0]; /* Command */ - txbuf[2] = msg->len + 4; /* Data + Hdr + 2 byte checksum */ - memcpy(&txbuf[3], &msg->data[1], (size_t)(msg->len-1)); + txbuf[1] = msg->data[0]; /* Command */ + txbuf[2] = msg->len + 4; /* Data + Hdr + 2 byte checksum */ + memcpy(&txbuf[3], &msg->data[1], (size_t)(msg->len - 1)); /* Checksum is 16 bit addition, in LSB order on packet */ for (i = 0, cksum = 0; i < (msg->len + 2); i++) { cksum += txbuf[i]; } - txbuf[msg->len+2] = (uint8_t) (cksum & 0xff); - txbuf[msg->len+3] = (uint8_t) ((cksum>>8) & 0xff); + txbuf[msg->len + 2] = (uint8_t)(cksum & 0xff); + txbuf[msg->len + 3] = (uint8_t)((cksum >> 8) & 0xff); - if ( (diag_l2_debug & DIAG_DEBUG_WRITE) && - (diag_l2_debug & DIAG_DEBUG_DATA)) { + if (diag_l2_debug_load() & (DIAG_DEBUG_WRITE | DIAG_DEBUG_DATA)) { fprintf(stderr, FLFMT "About to send %d bytes: ", FL, txbuf[2]); for (i = 0; i < txbuf[2]; i++) { fprintf(stderr, "0x%02X ", txbuf[i]); @@ -362,19 +347,17 @@ dl2p_mb1_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { fprintf(stderr, "\n"); } - rv = diag_l1_send (d_l2_conn->diag_link->l2_dl0d, 0, - txbuf, txbuf[2], d_l2_conn->diag_l2_p4min); - + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, txbuf, txbuf[2], + d_l2_conn->diag_l2_p4min); - return rv? diag_iseterr(rv):0 ; + return rv ? diag_iseterr(rv) : 0; } static struct diag_msg * -dl2p_mb1_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, - int *errval) { +dl2p_mb1_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval) { int rv; struct diag_msg *rmsg = NULL; - uint8_t rxbuf[MAXRBUF]; + uint8_t rxbuf[MAXRBUF]; rv = diag_l2_send(d_l2_conn, msg); if (rv < 0) { @@ -383,15 +366,13 @@ dl2p_mb1_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, } /* And wait for response for 1 second */ - rv = dl2p_mb1_int_recv(d_l2_conn, 1000, rxbuf, - sizeof(rxbuf)); + rv = dl2p_mb1_int_recv(d_l2_conn, 1000, rxbuf, sizeof(rxbuf)); - if (diag_l2_debug & DIAG_DEBUG_READ) { - fprintf(stderr, - FLFMT "msg receive conn %p got %d byte message\n", FL, + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "msg receive conn %p got %d byte message\n", FL, (void *)d_l2_conn, rv); } - if (rv < 5 || rv > (255+4)) { + if (rv < 5 || rv > (255 + 4)) { /* Bad, minimum message is 5 bytes, or error happened */ if (rv < 0) { *errval = rv; @@ -406,15 +387,14 @@ dl2p_mb1_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, if (rmsg == NULL) { return diag_pseterr(DIAG_ERR_NOMEM); } - rmsg->data[0] = rxbuf[1]; /* Command */ - memcpy(&rmsg->data[1], &rxbuf[3], (size_t)(rv - 3)); /* Data */ + rmsg->data[0] = rxbuf[1]; /* Command */ + memcpy(&rmsg->data[1], &rxbuf[3], (size_t)(rv - 3)); /* Data */ rmsg->rxtime = diag_os_getms(); rmsg->fmt = DIAG_FMT_FRAMED; } return rmsg; } - /* * Timeout, called to send idle packet to keep link to ECU alive */ @@ -426,18 +406,17 @@ dl2p_mb1_timeout(struct diag_l2_conn *d_l2_conn) { int rv; /* XXX Not async-signal-safe */ - if (diag_l2_debug & DIAG_DEBUG_TIMER) { - fprintf(stderr, FLFMT "timeout conn %p\n", FL, - (void *)d_l2_conn); + if (diag_l2_debug_load() & DIAG_DEBUG_TIMER) { + fprintf(stderr, FLFMT "timeout conn %p\n", FL, (void *)d_l2_conn); } - txbuf[0] = 0x50; /* Idle command */ + txbuf[0] = 0x50; /* Idle command */ txbuf[1] = 0x01; msg.data = txbuf; msg.len = 2; /* Use l2_send as it updates timeout timers */ - rv = diag_l2_send(d_l2_conn, &msg); + rv = diag_l2_send(d_l2_conn, &msg); /* And receive/ignore the response */ if (rv >= 0) { @@ -446,14 +425,13 @@ dl2p_mb1_timeout(struct diag_l2_conn *d_l2_conn) { return; } -const struct diag_l2_proto diag_l2_proto_mb1 = { - DIAG_L2_PROT_MB1, - "MB1", - DIAG_L2_FLAG_FRAMED | DIAG_L2_FLAG_KEEPALIVE, - dl2p_mb1_startcomms, - dl2p_mb1_stopcomms, - dl2p_mb1_send, - dl2p_mb1_recv, - dl2p_mb1_request, - dl2p_mb1_timeout -}; +const struct diag_l2_proto diag_l2_proto_mb1 = {DIAG_L2_PROT_MB1, + "MB1", + DIAG_L2_FLAG_FRAMED | + DIAG_L2_FLAG_KEEPALIVE, + dl2p_mb1_startcomms, + dl2p_mb1_stopcomms, + dl2p_mb1_send, + dl2p_mb1_recv, + dl2p_mb1_request, + dl2p_mb1_timeout}; diff --git a/scantool/diag_l2_mb1.h b/scantool/diag_l2_mb1.h index 6da7072f..5dc98c3e 100644 --- a/scantool/diag_l2_mb1.h +++ b/scantool/diag_l2_mb1.h @@ -35,5 +35,5 @@ extern "C" { #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L2_MB1_H_ */ diff --git a/scantool/diag_l2_raw.c b/scantool/diag_l2_raw.c index 6e6f85c5..70a07215 100644 --- a/scantool/diag_l2_raw.c +++ b/scantool/diag_l2_raw.c @@ -27,7 +27,6 @@ * */ - #include #include "diag.h" @@ -39,15 +38,9 @@ #include "diag_l2_raw.h" /* prototypes for this file */ - - - int -dl2p_raw_startcomms( struct diag_l2_conn *d_l2_conn, -UNUSED(flag_type flags), -unsigned int bitrate, -target_type target, -source_type source) { +dl2p_raw_startcomms(struct diag_l2_conn *d_l2_conn, UNUSED(flag_type flags), + unsigned int bitrate, target_type target, source_type source) { int rv; struct diag_serial_settings set; @@ -57,21 +50,21 @@ source_type source) { set.parflag = diag_par_n; /* Set the speed as shown */ - rv=diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_SETSPEED, &set); + rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_SETSPEED, &set); if (rv) { return diag_iseterr(DIAG_ERR_GENERAL); } - //set tgt and src address in d_l2_conn - d_l2_conn->diag_l2_destaddr=target; - d_l2_conn->diag_l2_srcaddr=source; + // set tgt and src address in d_l2_conn + d_l2_conn->diag_l2_destaddr = target; + d_l2_conn->diag_l2_srcaddr = source; return 0; } /* -*/ + */ int dl2p_raw_stopcomms(UNUSED(struct diag_l2_conn *pX)) { @@ -86,47 +79,47 @@ int dl2p_raw_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { int rv; - if (diag_l2_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "diag_l2_send %p, msg %p len %d called\n", - FL, (void *)d_l2_conn, (void *)msg, msg->len); + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "diag_l2_send %p, msg %p len %d called\n", FL, + (void *)d_l2_conn, (void *)msg, msg->len); } - rv = diag_l1_send (d_l2_conn->diag_link->l2_dl0d, 0, - msg->data, msg->len, d_l2_conn->diag_l2_p4min); + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, msg->data, msg->len, + d_l2_conn->diag_l2_p4min); - return rv? diag_iseterr(rv):0 ; + return rv ? diag_iseterr(rv) : 0; } /* -*/ + */ int dl2p_raw_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - void (*callback)(void *handle, struct diag_msg *msg), void *handle) { + void (*callback)(void *handle, struct diag_msg *msg), void *handle) { uint8_t rxbuf[MAXRBUF]; - struct diag_msg msg = {0}; //local message structure that will disappear when we return + struct diag_msg msg = {0}; // local message structure that will disappear when we + // return int rv; /* - * Read data from fd + * Read data from fd */ - rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, 0, - rxbuf, sizeof(rxbuf), timeout); + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, rxbuf, sizeof(rxbuf), timeout); if (rv <= 0) { /* Failure, or 0 bytes (which cant happen) */ return rv; } - msg.len = (uint8_t) rv; + msg.len = (uint8_t)rv; msg.data = rxbuf; /* This is raw, unframed data; we don't set .fmt */ msg.next = NULL; - msg.idata=NULL; + msg.idata = NULL; msg.rxtime = diag_os_getms(); - if (diag_l2_debug & DIAG_DEBUG_READ) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "l2_proto_raw_recv: handle=%p\n", FL, handle); //%pcallback! we won't try to printf the - //callback pointer. + // callback pointer. } /* @@ -140,10 +133,9 @@ dl2p_raw_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, } /* -*/ + */ struct diag_msg * -dl2p_raw_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, - int *errval) { +dl2p_raw_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval) { int rv; struct diag_msg *rmsg = NULL; uint8_t rxbuf[MAXRBUF]; @@ -155,8 +147,7 @@ dl2p_raw_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, } /* And wait for response */ - rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, - 0, rxbuf, sizeof(rxbuf), 1000); + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, rxbuf, sizeof(rxbuf), 1000); if (rv <= 0) { *errval = rv; @@ -170,21 +161,19 @@ dl2p_raw_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, if (rmsg == NULL) { return diag_pseterr(DIAG_ERR_NOMEM); } - memcpy(&rmsg->data, rxbuf, (size_t)rv); /* Data */ + memcpy(&rmsg->data, rxbuf, (size_t)rv); /* Data */ rmsg->fmt = 0; rmsg->rxtime = diag_os_getms(); return rmsg; } -const struct diag_l2_proto diag_l2_proto_raw = { - DIAG_L2_PROT_RAW, - "RAW", - 0, - dl2p_raw_startcomms, - dl2p_raw_stopcomms, - dl2p_raw_send, - dl2p_raw_recv, - dl2p_raw_request, - NULL -}; +const struct diag_l2_proto diag_l2_proto_raw = {DIAG_L2_PROT_RAW, + "RAW", + 0, + dl2p_raw_startcomms, + dl2p_raw_stopcomms, + dl2p_raw_send, + dl2p_raw_recv, + dl2p_raw_request, + NULL}; diff --git a/scantool/diag_l2_raw.h b/scantool/diag_l2_raw.h index 6cd35ed6..db310c17 100644 --- a/scantool/diag_l2_raw.h +++ b/scantool/diag_l2_raw.h @@ -30,40 +30,35 @@ */ /* -*/ + */ #if defined(__cplusplus) extern "C" { #endif -int -dl2p_raw_startcomms( struct diag_l2_conn *d_l2_conn, flag_type flags, - unsigned int bitrate, target_type target, source_type source); +int dl2p_raw_startcomms(struct diag_l2_conn *d_l2_conn, flag_type flags, + unsigned int bitrate, target_type target, source_type source); /* -*/ -int -dl2p_raw_stopcomms(struct diag_l2_conn *pX); + */ +int dl2p_raw_stopcomms(struct diag_l2_conn *pX); /* * Just send the data, with no processing etc */ -int -dl2p_raw_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg); +int dl2p_raw_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg); /* -*/ -int -dl2p_raw_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - void (*callback)(void *handle, struct diag_msg *msg), void *handle); + */ +int dl2p_raw_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, + void (*callback)(void *handle, struct diag_msg *msg), void *handle); /* -*/ + */ struct diag_msg * dl2p_raw_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval); - #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L2_RAW_H_ */ diff --git a/scantool/diag_l2_saej1850.c b/scantool/diag_l2_saej1850.c index dea6627d..66edfdcb 100644 --- a/scantool/diag_l2_saej1850.c +++ b/scantool/diag_l2_saej1850.c @@ -42,25 +42,24 @@ #include "diag_l2_saej1850.h" /* prototypes for this file */ - /* * SAEJ1850 specific data */ struct diag_l2_j1850 { - uint8_t type; /* FAST/SLOW/CARB */ + uint8_t type; /* FAST/SLOW/CARB */ - uint8_t srcaddr; /* Src address used */ - uint8_t dstaddr; /* Dest address used */ - //uint16_t modeflags; /* Flags XXXunused ! */ + uint8_t srcaddr; /* Src address used */ + uint8_t dstaddr; /* Dest address used */ + // uint16_t modeflags; /* Flags XXXunused ! */ uint8_t state; - uint8_t rxbuf[MAXRBUF]; /* Receive buffer, for building message in */ - int rxoffset; /* Offset to write into buffer */ + uint8_t rxbuf[MAXRBUF]; /* Receive buffer, for building message in */ + int rxoffset; /* Offset to write into buffer */ }; -#define STATE_CLOSED 0 /* Established comms */ -#define STATE_CONNECTING 1 /* Connecting */ -#define STATE_ESTABLISHED 2 /* Established */ +#define STATE_CLOSED 0 /* Established comms */ +#define STATE_CONNECTING 1 /* Connecting */ +#define STATE_ESTABLISHED 2 /* Established */ /* Prototypes */ uint8_t dl2p_j1850_crc(uint8_t *msg_buf, int nbytes); @@ -72,16 +71,15 @@ uint8_t dl2p_j1850_crc(uint8_t *msg_buf, int nbytes); */ static int -dl2p_j1850_startcomms(struct diag_l2_conn *d_l2_conn, -UNUSED(flag_type flags), -UNUSED(unsigned int bitrate), -target_type target, source_type source) { +dl2p_j1850_startcomms(struct diag_l2_conn *d_l2_conn, UNUSED(flag_type flags), + UNUSED(unsigned int bitrate), target_type target, + source_type source) { struct diag_l2_j1850 *dp; int rv; - if (diag_l2_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "diag_l2_j1850_startcomms dl2conn %p\n", - FL, (void *)d_l2_conn); + if (diag_l2_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "diag_l2_j1850_startcomms dl2conn %p\n", FL, + (void *)d_l2_conn); } rv = diag_calloc(&dp, 1); @@ -107,7 +105,7 @@ target_type target, source_type source) { } /* -*/ + */ static int dl2p_j1850_stopcomms(struct diag_l2_conn *d_l2_conn) { struct diag_l2_j1850 *dp; @@ -117,39 +115,38 @@ dl2p_j1850_stopcomms(struct diag_l2_conn *d_l2_conn) { if (dp) { free(dp); } - d_l2_conn->diag_l2_proto_data=NULL; + d_l2_conn->diag_l2_proto_data = NULL; /* Always OK for now */ return 0; } - /* Thanks to B. Roadman's web site for this CRC code */ uint8_t dl2p_j1850_crc(uint8_t *msg_buf, int nbytes) { - uint8_t crc_reg=0xff,poly,i,j; + uint8_t crc_reg = 0xff, poly, i, j; uint8_t *byte_point; uint8_t bit_point; - for (i=0, byte_point=msg_buf; i>=1) { - if (bit_point & *byte_point) { // case for new bit = 1 + for (i = 0, byte_point = msg_buf; i < nbytes; ++i, ++byte_point) { + for (j = 0, bit_point = 0x80; j < 8; ++j, bit_point >>= 1) { + if (bit_point & *byte_point) { // case for new bit = 1 if (crc_reg & 0x80) { - poly=1; // define the polynomial + poly = 1; // define the polynomial } else { poly = 0x1c; } - crc_reg= ( (crc_reg << 1) | 1) ^ poly; - } else { // case for new bit = 0 - poly=0; + crc_reg = ((crc_reg << 1) | 1) ^ poly; + } else { // case for new bit = 0 + poly = 0; if (crc_reg & 0x80) { poly = 0x1d; } - crc_reg= (crc_reg << 1) ^ poly; + crc_reg = (crc_reg << 1) ^ poly; } } } - return ~crc_reg; // Return CRC + return ~crc_reg; // Return CRC } /* @@ -166,10 +163,9 @@ dl2p_j1850_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { uint8_t buf[MAXRBUF]; int offset = 0; - if (diag_l2_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, - FLFMT "diag_l2_j1850_send %p msg %p len %d called\n", - FL, (void *)d_l2_conn, (void *)msg, msg->len); + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "diag_l2_j1850_send %p msg %p len %d called\n", FL, + (void *)d_l2_conn, (void *)msg, msg->len); } if ((msg->len + 4) >= MAXRBUF) { @@ -181,8 +177,8 @@ dl2p_j1850_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { l1protocol = d_l2_conn->diag_link->l1proto; if (l1flags & DIAG_L1_DATAONLY) { - //no headers to add, just the message - //nop + // no headers to add, just the message + // nop } else { // Add the J1850 header to the data @@ -201,23 +197,21 @@ dl2p_j1850_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { offset += msg->len; if (((l1flags & DIAG_L1_DOESL2CKSUM) == 0) && - ((l1flags & DIAG_L1_DATAONLY) == 0)) { + ((l1flags & DIAG_L1_DATAONLY) == 0)) { // Add in J1850 CRC int curoff = offset; buf[offset++] = dl2p_j1850_crc(buf, curoff); } - if (diag_l2_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, - FLFMT "diag_l2_j1850_send sending %d bytes to L1\n", FL, + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "diag_l2_j1850_send sending %d bytes to L1\n", FL, offset); } // And send data to Layer 1 - rv = diag_l1_send (d_l2_conn->diag_link->l2_dl0d, 0, - buf, (size_t)offset, 0); + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, buf, (size_t)offset, 0); - return rv? diag_iseterr(rv):0 ; + return rv ? diag_iseterr(rv) : 0; } /* @@ -233,9 +227,9 @@ static int dl2p_j1850_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { int rv; struct diag_l2_j1850 *dp; - unsigned long long t_done; //time elapsed - unsigned long long t_us; //total timeout, in us - unsigned long long t0; //start time + unsigned long long t_done; // time elapsed + unsigned long long t_us; // total timeout, in us + unsigned long long t0; // start time int l1flags = d_l2_conn->diag_link->l1flags; @@ -244,10 +238,11 @@ dl2p_j1850_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { dp = (struct diag_l2_j1850 *)d_l2_conn->diag_l2_proto_data; diag_freemsg(d_l2_conn->diag_msg); - if (diag_l2_debug & DIAG_DEBUG_READ) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, - FLFMT "diag_l2_j1850_int_recv offset 0x%X, " - "timeout=%u\n", + FLFMT + "diag_l2_j1850_int_recv offset 0x%X, " + "timeout=%u\n", FL, dp->rxoffset, timeout); } @@ -263,20 +258,21 @@ dl2p_j1850_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { dp->rxoffset = 0; - /* note : some of this is not necessary since we assume every L0/L1 does J1850 framing properly. */ + /* note : some of this is not necessary since we assume every L0/L1 does J1850 + * framing properly. */ while (t_done < t_us) { - //loop while there's time left + // loop while there's time left unsigned long tout; - struct diag_msg *tmsg; + struct diag_msg *tmsg; unsigned datalen; tout = timeout - (t_done / 1000); - //Unofficially, smart L0s (like ME,SIM) return max 1 response per call to l1_recv() - rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, NULL, - &dp->rxbuf[dp->rxoffset], - sizeof(dp->rxbuf) - dp->rxoffset, - tout); + // Unofficially, smart L0s (like ME,SIM) return max 1 response per call to + // l1_recv() + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, NULL, + &dp->rxbuf[dp->rxoffset], + sizeof(dp->rxbuf) - dp->rxoffset, tout); if (rv == DIAG_ERR_TIMEOUT) { break; @@ -289,7 +285,7 @@ dl2p_j1850_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { } dp->rxoffset += rv; - //update elapsed time + // update elapsed time t_done = diag_os_hrtus(diag_os_gethrt() - t0); if (rv == 0) { continue; // no data ? @@ -299,21 +295,21 @@ dl2p_j1850_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { // get data payload length if (!(l1flags & DIAG_L1_NOHDRS)) { - //headers present + // headers present if (datalen <= 3) { continue; } datalen -= 3; } if (!(l1flags & DIAG_L1_STRIPSL2CKSUM)) { - //CRC present + // CRC present if (datalen <= 1) { continue; } datalen -= 1; } - //alloc msg and analyze + // alloc msg and analyze tmsg = diag_allocmsg(datalen); if (tmsg == NULL) { diag_freemsg(d_l2_conn->diag_msg); @@ -321,27 +317,28 @@ dl2p_j1850_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { } if (!(l1flags & DIAG_L1_NOHDRS)) { - //get header content & trim + // get header content & trim tmsg->dest = dp->rxbuf[1]; tmsg->src = dp->rxbuf[2]; - //and copy, skipping header bytes. + // and copy, skipping header bytes. memcpy(tmsg->data, &dp->rxbuf[3], datalen); } else { memcpy(tmsg->data, dp->rxbuf, datalen); } if (!(l1flags & DIAG_L1_STRIPSL2CKSUM)) { - //test & trim checksum - uint8_t tcrc=dl2p_j1850_crc(dp->rxbuf, dp->rxoffset - 1); + // test & trim checksum + uint8_t tcrc = dl2p_j1850_crc(dp->rxbuf, dp->rxoffset - 1); if (dp->rxbuf[dp->rxoffset - 1] != tcrc) { - fprintf(stderr, "Bad checksum detected: needed %02X got %02X\n", - tcrc, dp->rxbuf[dp->rxoffset - 1]); + fprintf(stderr, + "Bad checksum detected: needed %02X got %02X\n", + tcrc, dp->rxbuf[dp->rxoffset - 1]); tmsg->fmt |= DIAG_FMT_BADCS; } } - tmsg->fmt |= DIAG_FMT_CKSUMMED; //either L1 did it or we just did + tmsg->fmt |= DIAG_FMT_CKSUMMED; // either L1 did it or we just did tmsg->fmt |= DIAG_FMT_FRAMED; tmsg->rxtime = diag_os_getms(); @@ -349,19 +346,17 @@ dl2p_j1850_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { diag_l2_addmsg(d_l2_conn, tmsg); - } //while !timed out + } // while !timed out dp->state = STATE_ESTABLISHED; return 0; } - static int dl2p_j1850_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - void (*callback)(void *handle, struct diag_msg *msg), - void *handle) { + void (*callback)(void *handle, struct diag_msg *msg), void *handle) { int rv; - struct diag_msg *tmsg; + struct diag_msg *tmsg; rv = dl2p_j1850_int_recv(d_l2_conn, timeout); @@ -377,12 +372,11 @@ dl2p_j1850_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, /* * We now have data stored on the L2 descriptor */ - if (diag_l2_debug & DIAG_DEBUG_READ) { - fprintf(stderr, - FLFMT "calling rcv msg=%p callback, handle=%p\n", FL, + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "calling rcv msg=%p callback, handle=%p\n", FL, (void *)d_l2_conn->diag_msg, handle); //%pcallback! we won't try to printf the - //callback pointer. + // callback pointer. } tmsg = d_l2_conn->diag_msg; @@ -396,7 +390,7 @@ dl2p_j1850_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, /* message no longer needed */ diag_freemsg(tmsg); - if (diag_l2_debug & DIAG_DEBUG_READ) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "rcv callback completed\n", FL); } @@ -407,8 +401,7 @@ dl2p_j1850_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, * Send a request and wait for a response */ static struct diag_msg * -dl2p_j1850_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, - int *errval) { +dl2p_j1850_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval) { int rv; struct diag_msg *rmsg = NULL; @@ -435,7 +428,7 @@ dl2p_j1850_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, /* Return the message to user, who is responsible for freeing it */ if (!d_l2_conn->diag_msg) { - //no response, but no error either + // no response, but no error either *errval = DIAG_ERR_TIMEOUT; } rmsg = d_l2_conn->diag_msg; @@ -443,14 +436,13 @@ dl2p_j1850_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, return rmsg; } -const struct diag_l2_proto diag_l2_proto_saej1850 = { - DIAG_L2_PROT_SAEJ1850, - "SAEJ1850", - DIAG_L2_FLAG_FRAMED | DIAG_L2_FLAG_CONNECTS_ALWAYS, - dl2p_j1850_startcomms, - dl2p_j1850_stopcomms, - dl2p_j1850_send, - dl2p_j1850_recv, - dl2p_j1850_request, - NULL -}; +const struct diag_l2_proto diag_l2_proto_saej1850 = {DIAG_L2_PROT_SAEJ1850, + "SAEJ1850", + DIAG_L2_FLAG_FRAMED | + DIAG_L2_FLAG_CONNECTS_ALWAYS, + dl2p_j1850_startcomms, + dl2p_j1850_stopcomms, + dl2p_j1850_send, + dl2p_j1850_recv, + dl2p_j1850_request, + NULL}; diff --git a/scantool/diag_l2_saej1850.h b/scantool/diag_l2_saej1850.h index 57292400..85a3ab19 100644 --- a/scantool/diag_l2_saej1850.h +++ b/scantool/diag_l2_saej1850.h @@ -32,8 +32,7 @@ extern "C" { #endif - #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L2_SAEJ1850_H_ */ diff --git a/scantool/diag_l2_test.c b/scantool/diag_l2_test.c index bfb6d413..5915eac8 100644 --- a/scantool/diag_l2_test.c +++ b/scantool/diag_l2_test.c @@ -1,77 +1,80 @@ /* * freediag - Vehicle Diagnostic Utility * - * Copyright (C) 2017-2018 fenugrec + * Copyright (C) 2017-2018 fenugrec * * Test L2 driver. Only intended for use by diag_test.c * to exercise low-level libdiag code paths. * */ - #include "diag.h" #include "diag_l2.h" #include "diag_err.h" #include "diag_os.h" -#define TEST_TIMER_DURATION 500 /** time (ms) before returning from timer callback func */ - +#define TEST_TIMER_DURATION \ + 500 /** time (ms) before returning from timer callback func \ + */ -int dl2p_test_startcomms( struct diag_l2_conn *dl2c, flag_type flags, - unsigned int bitrate, target_type target, source_type source) { - (void) dl2c; - (void) flags; - (void) bitrate; - (void) target; - (void) source; +int +dl2p_test_startcomms(struct diag_l2_conn *dl2c, flag_type flags, unsigned int bitrate, + target_type target, source_type source) { + (void)dl2c; + (void)flags; + (void)bitrate; + (void)target; + (void)source; return 0; } /* -*/ + */ -int dl2p_test_stopcomms(struct diag_l2_conn *pX) { - (void) pX; +int +dl2p_test_stopcomms(struct diag_l2_conn *pX) { + (void)pX; return 0; } -int dl2p_test_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { - (void) d_l2_conn; - (void) msg; +int +dl2p_test_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { + (void)d_l2_conn; + (void)msg; return diag_iseterr(DIAG_ERR_BADVAL); } -int dl2p_test_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - void (*callback)(void *handle, struct diag_msg *msg), void *handle) { - (void) d_l2_conn; - (void) timeout; - (void) callback; - (void) handle; +int +dl2p_test_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, + void (*callback)(void *handle, struct diag_msg *msg), void *handle) { + (void)d_l2_conn; + (void)timeout; + (void)callback; + (void)handle; return diag_iseterr(DIAG_ERR_BADVAL); } -struct diag_msg * dl2p_test_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, - int *errval) { - (void) d_l2_conn; - (void) msg; +struct diag_msg * +dl2p_test_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval) { + (void)d_l2_conn; + (void)msg; *errval = DIAG_ERR_GENERAL; return diag_pseterr(DIAG_ERR_BADVAL); } -void dl2p_test_timer(struct diag_l2_conn *dl2c) { - (void) dl2c; +void +dl2p_test_timer(struct diag_l2_conn *dl2c) { + (void)dl2c; diag_os_millisleep(TEST_TIMER_DURATION); return; } -const struct diag_l2_proto diag_l2_proto_test = { - DIAG_L2_PROT_TEST, - "TEST", - 0, - dl2p_test_startcomms, - dl2p_test_stopcomms, - dl2p_test_send, - dl2p_test_recv, - dl2p_test_request, - dl2p_test_timer -}; +const struct diag_l2_proto diag_l2_proto_test = {DIAG_L2_PROT_TEST, + "TEST", + 0, + dl2p_test_startcomms, + dl2p_test_stopcomms, + dl2p_test_send, + dl2p_test_recv, + dl2p_test_request, + dl2p_test_timer}; diff --git a/scantool/diag_l2_vag.c b/scantool/diag_l2_vag.c index b6c4acec..78d94271 100644 --- a/scantool/diag_l2_vag.c +++ b/scantool/diag_l2_vag.c @@ -61,16 +61,18 @@ * ISO vag specific data */ struct diag_l2_vag { - uint8_t seq_nr; //Sequence number - uint8_t master; //Master flag, 1 = us, 0 = ECU + uint8_t seq_nr; // Sequence number + uint8_t master; // Master flag, 1 = us, 0 = ECU uint8_t first_telegram_started; - struct diag_msg *ecu_id_telegram; //a pointer to store the ECU ID telegram received during initiation + struct diag_msg *ecu_id_telegram; // a pointer to store the ECU ID telegram + // received during initiation - uint8_t rxbuf[MAXRBUF]; //Receive buffer, for building message in - int rxoffset; //Offset to write into buffer + uint8_t rxbuf[MAXRBUF]; // Receive buffer, for building message in + int rxoffset; // Offset to write into buffer - unsigned long long msg_finish_time; //a point in time when the last message finished arriving/departing + unsigned long long msg_finish_time; // a point in time when the last message + // finished arriving/departing }; /* @@ -87,7 +89,7 @@ static struct diag_msg * diag_l2_vag_block_recv(struct diag_l2_conn *d_l2_conn, int *errval, int msg_timeout) { int rv; struct diag_l2_vag *dp = (struct diag_l2_vag *)d_l2_conn->diag_l2_proto_data; - //prepare a No Acknowledge message - we may need one + // prepare a No Acknowledge message - we may need one uint8_t noack_data[1]; struct diag_msg noack; memset(&noack, 0, sizeof(noack)); @@ -95,72 +97,86 @@ diag_l2_vag_block_recv(struct diag_l2_conn *d_l2_conn, int *errval, int msg_time noack.data = noack_data; noack.len = 1; - //clear the offset + // clear the offset dp->rxoffset = 0; - //Set the timeout for the first byte of the awaited message + // Set the timeout for the first byte of the awaited message int timeout = msg_timeout; while (1) { if (d_l2_conn->diag_link->l1flags & DIAG_L1_DOESL2FRAME) { - //for framed L0, must read the whole frame at once - rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, dp->rxbuf, MAXRBUF, timeout); - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "after recv, rv=%d\n", FL, - rv); + // for framed L0, must read the whole frame at once + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, dp->rxbuf, + MAXRBUF, timeout); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "after recv, rv=%d\n", FL, rv); } if (rv < 0) { *errval = rv; return diag_pseterr(rv); } dp->msg_finish_time = diag_os_gethrt(); - //currently the only framed L0 for KW1281 is carsim, so don't bother validating sequence number + // currently the only framed L0 for KW1281 is carsim, so don't + // bother validating sequence number break; } - //one byte at a time is sent by the ECU + // one byte at a time is sent by the ECU uint8_t byte; rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &byte, 1, timeout); unsigned long long byte_recv_time = diag_os_gethrt(); - //now set the timeout value for all the remaining awaited bytes + // now set the timeout value for all the remaining awaited bytes timeout = KWP1281_T_R8; - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "after recv, rv=%d rxoffset=%d\n", - FL, rv, dp->rxoffset); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "after recv, rv=%d rxoffset=%d\n", FL, rv, + dp->rxoffset); } if (rv < 0) { if (rv == DIAG_ERR_TIMEOUT) { - //a very special case of timeout is when waiting for the first telegram from the ECU; - //if it occurs, then it means that the ECU either received wrong KB2 complement - //(which is more probable) or didn't receive the KB2 at all (less probable); - //since we cannot OR the error code, let's return the more probable one + // a very special case of timeout is when waiting for the + // first telegram from the ECU; if it occurs, then it means + // that the ECU either received wrong KB2 complement (which + // is more probable) or didn't receive the KB2 at all (less + // probable); since we cannot OR the error code, let's + // return the more probable one if (dp->first_telegram_started == 0) { - *errval = DIAG_ERR_BADRATE; //wrong KB2 value indicates baud rate problems + *errval = DIAG_ERR_BADRATE; // wrong KB2 value + // indicates baud rate + // problems return diag_pseterr(*errval); } - //the timeout may occur if the transmitter didn't receive our complement byte - //or if that byte was incorrect - in such cases it will retry sending the whole - //message again, but only after 2*T_R8 time units since it sent the previous message byte; - //we (the receiver) have been waiting already for T_R8 time unit since sending our - //complement byte, so the transmitter should re-start the message _within_ - //_our_ another T_R8 time unit (which started later than the receiver's secont T_R8 - //time unit); - rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &byte, 1, KWP1281_T_R8); + // the timeout may occur if the transmitter didn't receive + // our complement byte or if that byte was incorrect - in + // such cases it will retry sending the whole message + // again, but only after 2*T_R8 time units since it sent + // the previous message byte; we (the receiver) have been + // waiting already for T_R8 time unit since sending our + // complement byte, so the transmitter should re-start the + // message _within_ _our_ another T_R8 time unit (which + // started later than the receiver's secont T_R8 time + // unit); + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &byte, + 1, KWP1281_T_R8); if (rv < 0) { - //if we timed out again, then this means that the communication line - //has been broken or closed; but with one exception - if we were waiting for - //the last byte of the message (the ETX byte), then we should assume that the ETX - //byte might have been sent by the transmitter, but got lost on its way, - //and we should try to go on as if we have received it - if (dp->rxoffset < dp->rxbuf[0] || rv != DIAG_ERR_TIMEOUT) { + // if we timed out again, then this means that the + // communication line has been broken or closed; + // but with one exception - if we were waiting for + // the last byte of the message (the ETX byte), + // then we should assume that the ETX byte might + // have been sent by the transmitter, but got lost + // on its way, and we should try to go on as if we + // have received it + if (dp->rxoffset < dp->rxbuf[0] || + rv != DIAG_ERR_TIMEOUT) { *errval = rv; return diag_pseterr(rv); } } else { - //the first byte of the re-started message has arrived, so just reset the rxoffset - //and go on with the regular code path + // the first byte of the re-started message has + // arrived, so just reset the rxoffset and go on + // with the regular code path dp->rxoffset = 0; } } else { @@ -168,69 +184,89 @@ diag_l2_vag_block_recv(struct diag_l2_conn *d_l2_conn, int *errval, int msg_time return diag_pseterr(rv); } } - //now we can set the flag indicating that the initialization - //has been fully successful + // now we can set the flag indicating that the initialization + // has been fully successful if (dp->first_telegram_started == 0) { dp->first_telegram_started = 1; } - //store the byte + // store the byte dp->rxbuf[dp->rxoffset] = byte; dp->rxoffset++; - //is this the last byte? - if (dp->rxoffset-1 == dp->rxbuf[0]) { + // is this the last byte? + if (dp->rxoffset - 1 == dp->rxbuf[0]) { dp->msg_finish_time = diag_os_gethrt(); - //check whether the last byte is correct + // check whether the last byte is correct if (byte != KWP1281_END_BYTE || - //check also whether the sequence number present in the message is correct - //(should be odd and be greater than our sequence number by 1) - ((dp->rxbuf[1] % 2) == 0 || dp->rxbuf[1] != dp->seq_nr+1)) { - //arbitrarily set our sequence number - we could get here because of an incorrect - //sequence number sent by the ECU + // check also whether the sequence number present in the + // message is correct (should be odd and be greater than our + // sequence number by 1) + ((dp->rxbuf[1] % 2) == 0 || dp->rxbuf[1] != dp->seq_nr + 1)) { + // arbitrarily set our sequence number - we could get here + // because of an incorrect sequence number sent by the ECU dp->seq_nr += 2; - //send a NoAck Retry message by using the sequence number from the ECU's message - //(we can be sure that the buffer contains the number that ECU sent us, because when we received it, - //we responded with a complement and ECU didn't complain) + // send a NoAck Retry message by using the sequence number + // from the ECU's message (we can be sure that the buffer + // contains the number that ECU sent us, because when we + // received it, we responded with a complement and ECU + // didn't complain) noack_data[0] = dp->rxbuf[1]; - //we must flag ourselves as master before calling the send function - //(and the send function will re-set the flag to slave) + // we must flag ourselves as master before calling the send + // function (and the send function will re-set the flag to + // slave) dp->master = 1; rv = diag_l2_send(d_l2_conn, &noack); if (rv < 0) { *errval = rv; return diag_pseterr(rv); } - //set the old sequence number again - //NOTE: SAE J2818 says that "The Message number is NOT incremented by the transmitter for a repeated block." - // so we should expect that the repeated message will have the same sequence number and thus we should - // decrease our own sequence number to the previous value also. However, when testing on an ECU installed - // in a European VW, this is not the case - the ECU repeated the message with an increased sequence number. - // Can't test this with a VW from USA, so commenting-out for now. If US VWs indeed follow the specification - // strictly, then a possible solution would be to set/unset this behaviour based on a flag - // (eg. L2_vag specific option for enabling/disabling strict SAE J2818). - //dp->seq_nr -= 2; - //prepare for receiving the whole message again + // set the old sequence number again + // NOTE: SAE J2818 says that "The Message number is NOT + // incremented by the transmitter for a repeated block." + // so we should expect that the repeated message will + // have the same sequence number and thus we should + // decrease our own sequence number to the previous + // value also. However, when testing on an ECU + // installed in a European VW, this is not the case - + // the ECU repeated the message with an increased + // sequence number. Can't test this with a VW from + // USA, so commenting-out for now. If US VWs indeed + // follow the specification strictly, then a possible + // solution would be to set/unset this behaviour based + // on a flag (eg. L2_vag specific option for + // enabling/disabling strict SAE J2818). + // dp->seq_nr -= 2; + // prepare for receiving the whole message again dp->rxoffset = 0; - //time elapsed since receiving last message - unsigned long long elapsed_time = diag_os_hrtus(diag_os_gethrt() - dp->msg_finish_time)/1000; - //the timeout values are between messages, so decrease the T_RB_MAX timeout - //by the time that has elapsed since sending the no-ack message to the ECU - timeout = elapsed_time < KWP1281_T_RB_MAX ? KWP1281_T_RB_MAX-elapsed_time : 0; + // time elapsed since receiving last message + unsigned long long elapsed_time = + diag_os_hrtus(diag_os_gethrt() - + dp->msg_finish_time) / + 1000; + // the timeout values are between messages, so decrease the + // T_RB_MAX timeout by the time that has elapsed since + // sending the no-ack message to the ECU + timeout = elapsed_time < KWP1281_T_RB_MAX + ? KWP1281_T_RB_MAX - elapsed_time + : 0; continue; } break; } - //calculate the complement byte + // calculate the complement byte byte = ~byte; - //how much time elapsed since receiving another byte? - unsigned long long elapsed_time = diag_os_hrtus(diag_os_gethrt() - byte_recv_time)/1000; - //give ECU some time before sending the complement byte - diag_os_millisleep(elapsed_time < KWP1281_T_R6_MIN ? KWP1281_T_R6_MIN-elapsed_time : 0); + // how much time elapsed since receiving another byte? + unsigned long long elapsed_time = + diag_os_hrtus(diag_os_gethrt() - byte_recv_time) / 1000; + // give ECU some time before sending the complement byte + diag_os_millisleep(elapsed_time < KWP1281_T_R6_MIN + ? KWP1281_T_R6_MIN - elapsed_time + : 0); rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, &byte, 1, 0); - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "after send, rv=%d\n", FL, rv); } @@ -240,34 +276,36 @@ diag_l2_vag_block_recv(struct diag_l2_conn *d_l2_conn, int *errval, int msg_time } } - //now we are the master (!!) + // now we are the master (!!) dp->master = 1; - //update our sequence number + // update our sequence number //(the sequence number from the ECU's message has been validated already) - dp->seq_nr = dp->rxbuf[1]+1; + dp->seq_nr = dp->rxbuf[1] + 1; - //length of the data inside the block; - //the length byte (the first one) doesn't count itself, - //so subtract only three bytes: block counter, command title, the end byte - uint8_t data_length = dp->rxbuf[0]-3; + // length of the data inside the block; + // the length byte (the first one) doesn't count itself, + // so subtract only three bytes: block counter, command title, the end byte + uint8_t data_length = dp->rxbuf[0] - 3; - //alloc new message + // alloc new message struct diag_msg *tmsg = diag_allocmsg(data_length); if (tmsg == NULL) { *errval = DIAG_ERR_NOMEM; return diag_pseterr(*errval); } - //copy the message data, if exists + // copy the message data, if exists if (data_length > 0) { memcpy(tmsg->data, &dp->rxbuf[3], (size_t)data_length); } - //set the message info + // set the message info tmsg->rxtime = diag_os_getms(); tmsg->type = dp->rxbuf[2]; - tmsg->dest = tmsg->src = 0; //these are not used by the protocol (no such info in message blocks) - tmsg->fmt |= DIAG_FMT_CKSUMMED; //no real checksum, but the inverted bytes thing assures data integrity + tmsg->dest = tmsg->src = 0; // these are not used by the protocol (no such info in + // message blocks) + tmsg->fmt |= DIAG_FMT_CKSUMMED; // no real checksum, but the inverted bytes thing + // assures data integrity *errval = 0; return tmsg; } @@ -284,25 +322,27 @@ diag_l2_vag_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { unsigned long long elapsed_time, msg_timeout; int rv, na_retry_cnt = 0; - //Clear out last received message if not done already + // Clear out last received message if not done already if (d_l2_conn->diag_msg) { diag_freemsg(d_l2_conn->diag_msg); d_l2_conn->diag_msg = NULL; } - //ECU can send a telegram consisting of multiple messages, but it will expect us - //to send an ACK message after every part (message) of the telegram, so prepare one + // ECU can send a telegram consisting of multiple messages, but it will expect us + // to send an ACK message after every part (message) of the telegram, so prepare + // one memset(&ack, 0, sizeof(ack)); ack.type = KWP1281_SID_ACK; - //how much time has elapsed since sending our message to the ECU - elapsed_time = diag_os_hrtus(diag_os_gethrt() - dp->msg_finish_time)/1000; - //timeout while waiting for a message - msg_timeout = elapsed_time < timeout ? timeout-elapsed_time : 0; + // how much time has elapsed since sending our message to the ECU + elapsed_time = diag_os_hrtus(diag_os_gethrt() - dp->msg_finish_time) / 1000; + // timeout while waiting for a message + msg_timeout = elapsed_time < timeout ? timeout - elapsed_time : 0; while (1) { - //receive another message - struct diag_msg *tmsg = diag_l2_vag_block_recv(d_l2_conn, &rv, msg_timeout); + // receive another message + struct diag_msg *tmsg = + diag_l2_vag_block_recv(d_l2_conn, &rv, msg_timeout); if (rv < 0) { if (d_l2_conn->diag_msg) { diag_freemsg(d_l2_conn->diag_msg); @@ -311,44 +351,49 @@ diag_l2_vag_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { return diag_iseterr(rv); } - //if this is the first messag sent by the ECU in the current telegram and this is either - //ACK or NO_ACK, then pass it to the caller - we cannot do anything about NO_ACK if it was - //caused by something we didn't send; and if ECU responded only with ACK, then the caller should - //be informed that there is no other response from the ECU (for instance, the keep-alive routine - //will be interested in an ACK reply) - if (d_l2_conn->diag_msg == NULL && (tmsg->type == KWP1281_SID_ACK || tmsg->type == KWP1281_SID_NO_ACK)) { + // if this is the first messag sent by the ECU in the current telegram and + // this is either ACK or NO_ACK, then pass it to the caller - we cannot do + // anything about NO_ACK if it was caused by something we didn't send; and + // if ECU responded only with ACK, then the caller should be informed that + // there is no other response from the ECU (for instance, the keep-alive + // routine will be interested in an ACK reply) + if (d_l2_conn->diag_msg == NULL && + (tmsg->type == KWP1281_SID_ACK || tmsg->type == KWP1281_SID_NO_ACK)) { diag_l2_addmsg(d_l2_conn, tmsg); - if ((diag_l2_debug & DIAG_DEBUG_DATA) && (diag_l2_debug & DIAG_DEBUG_PROTO)) { - fprintf(stderr, FLFMT "Copying %u bytes to data: ", FL, tmsg->len); + if ((diag_l2_debug_load() & DIAG_DEBUG_DATA) && + (diag_l2_debug_load() & DIAG_DEBUG_PROTO)) { + fprintf(stderr, FLFMT "Copying %u bytes to data: ", FL, + tmsg->len); diag_data_dump(stderr, tmsg->data, tmsg->len); fprintf(stderr, "\n"); } break; } - //if the ECU has responded with an ACK message to our ACK message, then it means that - //the telegram has finished with the previous received message + // if the ECU has responded with an ACK message to our ACK message, then it + // means that the telegram has finished with the previous received message if (tmsg->type == KWP1281_SID_ACK) { - //we don't need the just-received ACK message + // we don't need the just-received ACK message diag_freemsg(tmsg); break; } - //if this is a NO_ACK message (sent by the ECU as a response to our ACK), - //then we will re-try with that ACK + // if this is a NO_ACK message (sent by the ECU as a response to our ACK), + // then we will re-try with that ACK if (tmsg->type == KWP1281_SID_NO_ACK) { - //check if it is NO_ACK Retry - if (tmsg->data[0] == dp->seq_nr-2) { - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + // check if it is NO_ACK Retry + if (tmsg->data[0] == dp->seq_nr - 2) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "Received No Acknowledge - " "Retry message\n", FL); } - //accept at most KWP1281_NA_RETRIES of No Ack Retry messages in a row + // accept at most KWP1281_NA_RETRIES of No Ack Retry + // messages in a row if (++na_retry_cnt == KWP1281_NA_RETRIES) { - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "\tbut too many Retry " @@ -360,47 +405,58 @@ diag_l2_vag_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { d_l2_conn->diag_msg = NULL; return diag_iseterr(DIAG_ERR_ECUSAIDNO); } - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, - FLFMT "\tso will retry\n", FL); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "\tso will retry\n", FL); } - //re-send with the previous sequence number - //NOTE: SAE J2818 says that "The Message number is NOT incremented by the transmitter for a repeated block." - // so we should send the repeated message with the same sequence number as the original message. - // However, when testing this on an ECU installed in a European VW the ECU didn't accept such a message - // (responded with another NO_ACK Retry) and a repeated message with an incremented sequence number - // was accepted. - // Can't test this with a VW from USA, so commenting-out for now. If US VWs indeed follow the specification - // strictly, then a possible solution would be to set/unset this behaviour based on a flag - // (eg. L2_vag specific option for enabling/disabling strict SAE J2818). - //dp->seq_nr -= 2; + // re-send with the previous sequence number + // NOTE: SAE J2818 says that "The Message number is NOT + // incremented by the transmitter for a repeated block." + // so we should send the repeated message with the + // same sequence number as the original message. + // However, when testing this on an ECU installed in a + // European VW the ECU didn't accept such a message + // (responded with another NO_ACK Retry) and a + // repeated message with an incremented sequence + // number was accepted. Can't test this with a VW from + // USA, so commenting-out for now. If US VWs indeed + // follow the specification strictly, then a possible + // solution would be to set/unset this behaviour based + // on a flag (eg. L2_vag specific option for + // enabling/disabling strict SAE J2818). + // dp->seq_nr -= 2; } } else { - //add the new block to the telegram + // add the new block to the telegram diag_l2_addmsg(d_l2_conn, tmsg); if (d_l2_conn->diag_msg == tmsg) { - if ((diag_l2_debug & DIAG_DEBUG_DATA) && (diag_l2_debug & DIAG_DEBUG_PROTO)) { - fprintf(stderr, FLFMT "Copying %u bytes to data: ", FL, tmsg->len); + if ((diag_l2_debug_load() & DIAG_DEBUG_DATA) && + (diag_l2_debug_load() & DIAG_DEBUG_PROTO)) { + fprintf(stderr, + FLFMT "Copying %u bytes to data: ", FL, + tmsg->len); diag_data_dump(stderr, tmsg->data, tmsg->len); fprintf(stderr, "\n"); } } - //reset the counter of No Ack Retry messages received in a row + // reset the counter of No Ack Retry messages received in a row na_retry_cnt = 0; } - //now tell the ECU that we are waiting for morr! + // now tell the ECU that we are waiting for morr! rv = diag_l2_send(d_l2_conn, &ack); if (rv < 0) { - //clean up and set the error code + // clean up and set the error code diag_freemsg(d_l2_conn->diag_msg); d_l2_conn->diag_msg = NULL; return diag_iseterr(rv); } - //re-calculate the message timeout - elapsed_time = diag_os_hrtus(diag_os_gethrt() - dp->msg_finish_time)/1000; - msg_timeout = elapsed_time < KWP1281_T_RB_MAX ? KWP1281_T_RB_MAX-elapsed_time : 0; + // re-calculate the message timeout + elapsed_time = + diag_os_hrtus(diag_os_gethrt() - dp->msg_finish_time) / 1000; + msg_timeout = elapsed_time < KWP1281_T_RB_MAX + ? KWP1281_T_RB_MAX - elapsed_time + : 0; } return 0; @@ -417,7 +473,7 @@ diag_l2_vag_int_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout) { static int dl2p_vag_startcomms(struct diag_l2_conn *d_l2_conn, UNUSED(flag_type flags), - unsigned int bitrate, target_type target, UNUSED(source_type source)) { + unsigned int bitrate, target_type target, UNUSED(source_type source)) { struct diag_serial_settings set; struct diag_l2_vag *dp; int rv; @@ -431,7 +487,7 @@ dl2p_vag_startcomms(struct diag_l2_conn *d_l2_conn, UNUSED(flag_type flags), } d_l2_conn->diag_l2_proto_data = (void *)dp; - //set several initial values needed by checks performed in the send/receive code + // set several initial values needed by checks performed in the send/receive code dp->seq_nr = 0; dp->master = 0; dp->ecu_id_telegram = NULL; @@ -447,103 +503,106 @@ dl2p_vag_startcomms(struct diag_l2_conn *d_l2_conn, UNUSED(flag_type flags), set.stopbits = diag_stopbits_1; set.parflag = diag_par_n; - //Set the speed as shown + // Set the speed as shown rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_SETSPEED, &set); if (rv < 0) { free(dp); - d_l2_conn->diag_l2_proto_data=NULL; + d_l2_conn->diag_l2_proto_data = NULL; return diag_iseterr(rv); } - //Flush unread input, then wait for idle bus. + // Flush unread input, then wait for idle bus. (void)diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_IFLUSH, NULL); diag_os_millisleep(KWP1281_T_R0); - //Now do 5 baud init of supplied address + // Now do 5 baud init of supplied address in.type = DIAG_L1_INITBUS_5BAUD; in.addr = target; - //NOTE: there is no way to pass the timeout value into the init function - KWP1281_T_R1_MAX + // NOTE: there is no way to pass the timeout value into the init function - + // KWP1281_T_R1_MAX rv = diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_INITBUS, &in); if (rv < 0) { free(dp); - d_l2_conn->diag_l2_proto_data=NULL; + d_l2_conn->diag_l2_proto_data = NULL; return diag_iseterr(rv); } - //Mode bytes are in 7-Odd-1, read as 8N1 and ignore parity + // Mode bytes are in 7-Odd-1, read as 8N1 and ignore parity rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, cbuf, 1, KWP1281_T_R2_MAX); if (rv < 0) { free(dp); - d_l2_conn->diag_l2_proto_data=NULL; + d_l2_conn->diag_l2_proto_data = NULL; return diag_iseterr(rv); } rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &cbuf[1], 1, KWP1281_T_R3_MAX); if (rv < 0) { free(dp); - d_l2_conn->diag_l2_proto_data=NULL; + d_l2_conn->diag_l2_proto_data = NULL; return diag_iseterr(rv); } - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, - FLFMT - "Received KeyWord bytes: KB1: 0x%.2X\tKB2: 0x%.2X\n", + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "Received KeyWord bytes: KB1: 0x%.2X\tKB2: 0x%.2X\n", FL, cbuf[0], cbuf[1]); } - //Note down the bytes + // Note down the bytes d_l2_conn->diag_l2_kb1 = cbuf[0]; d_l2_conn->diag_l2_kb2 = cbuf[1]; - //transmit the inverted KB2 so that the ECU knows we have received it - //and can validate if we got it wrong (and can act accordingly, which - //essentially means it will timeout us if anything went wrong) + // transmit the inverted KB2 so that the ECU knows we have received it + // and can validate if we got it wrong (and can act accordingly, which + // essentially means it will timeout us if anything went wrong) if ((d_l2_conn->diag_link->l1flags & DIAG_L1_DOESSLOWINIT) == 0) { - //can transmit the invrted KB2 only after R4_MIN, - //so that the ECU has time to switch to receive mode + // can transmit the invrted KB2 only after R4_MIN, + // so that the ECU has time to switch to receive mode diag_os_millisleep(KWP1281_T_R4_MIN); - //Now transmit KB2 inverted - cbuf[0] = ~ d_l2_conn->diag_l2_kb2; - rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, cbuf, 1, d_l2_conn->diag_l2_p4min); + // Now transmit KB2 inverted + cbuf[0] = ~d_l2_conn->diag_l2_kb2; + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, cbuf, 1, + d_l2_conn->diag_l2_p4min); if (rv < 0) { free(dp); - d_l2_conn->diag_l2_proto_data=NULL; + d_l2_conn->diag_l2_proto_data = NULL; return diag_iseterr(rv); } } - //update the message finish time so that when waiting for the first ECU message - //a correct timeout can be calculated + // update the message finish time so that when waiting for the first ECU message + // a correct timeout can be calculated dp->msg_finish_time = diag_os_gethrt(); - //the first ECU telegram should now arrive + // the first ECU telegram should now arrive rv = diag_l2_vag_int_recv(d_l2_conn, KWP1281_T_R5_MAX); if (rv < 0) { - //if the error was a timeout while waiting for the very first byte of the telegram, - //then the error will be set to DIAG_ERR_BADRATE, which means that the ECU informs - //us that we have probably set incorrect baudrate (it must have received incorrect - //KB2 complement, and it can happen if we are using incorrect baudrate); - //ECU will re-try sending the synchronization byte in a moment, but since we are - //using a user-provided baudrate (instead of decoding it from the sync byte), then - //we cannot do anything about it here; so just report the error and leave + // if the error was a timeout while waiting for the very first byte of the + // telegram, then the error will be set to DIAG_ERR_BADRATE, which means + // that the ECU informs us that we have probably set incorrect baudrate (it + // must have received incorrect KB2 complement, and it can happen if we are + // using incorrect baudrate); ECU will re-try sending the synchronization + // byte in a moment, but since we are using a user-provided baudrate + // (instead of decoding it from the sync byte), then we cannot do anything + // about it here; so just report the error and leave free(dp); - d_l2_conn->diag_l2_proto_data=NULL; + d_l2_conn->diag_l2_proto_data = NULL; return diag_iseterr(rv); } - //the first telegram is now stored in d_l2_conn->diag_msg - copy its address - //to the dp->ecu_id_telegram pointer + // the first telegram is now stored in d_l2_conn->diag_msg - copy its address + // to the dp->ecu_id_telegram pointer dp->ecu_id_telegram = d_l2_conn->diag_msg; d_l2_conn->diag_msg = NULL; - //message interval for use by external timeout handler for sending keep-alive messages - d_l2_conn->tinterval = KWP1281_T_RB/2; + // message interval for use by external timeout handler for sending keep-alive + // messages + d_l2_conn->tinterval = KWP1281_T_RB / 2; return 0; } -//free what _startcomms alloc'ed -static int dl2p_vag_stopcomms(struct diag_l2_conn *d_l2_conn) { - //according to SAE J2818 if we want to finish the session - //we should just stop sending anything and let the ECU timeout; - //but of course l3 can implement the endcomms SID +// free what _startcomms alloc'ed +static int +dl2p_vag_stopcomms(struct diag_l2_conn *d_l2_conn) { + // according to SAE J2818 if we want to finish the session + // we should just stop sending anything and let the ECU timeout; + // but of course l3 can implement the endcomms SID struct diag_l2_vag *dp = (struct diag_l2_vag *)d_l2_conn->diag_l2_proto_data; if (dp != NULL) { if (dp->ecu_id_telegram != NULL) { @@ -558,7 +617,7 @@ static int dl2p_vag_stopcomms(struct diag_l2_conn *d_l2_conn) { d_l2_conn->diag_msg = NULL; } - //make sure the ECU detects the timeout + // make sure the ECU detects the timeout diag_os_millisleep(KWP1281_T_RB_MAX); return 0; } @@ -570,48 +629,50 @@ static int dl2p_vag_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { int rv = 0; - if (diag_l2_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, - FLFMT "diag_l2_vag_send %p msg %p len %d called\n", FL, + if (diag_l2_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "diag_l2_vag_send %p msg %p len %d called\n", FL, (void *)d_l2_conn, (void *)msg, msg->len); } struct diag_l2_vag *dp = (struct diag_l2_vag *)d_l2_conn->diag_l2_proto_data; - //if this function is called right after receiving the first ECU telegram, - //then it means that the caller doesn't care about the telegram, so delete it + // if this function is called right after receiving the first ECU telegram, + // then it means that the caller doesn't care about the telegram, so delete it if (dp->ecu_id_telegram != NULL) { diag_freemsg(dp->ecu_id_telegram); dp->ecu_id_telegram = NULL; } - //are we master? if not then the caller should be redesigned/fixed + // are we master? if not then the caller should be redesigned/fixed assert(dp->master == 1); - //the length of the block (counter byte, title byte, data bytes and block end byte) + // the length of the block (counter byte, title byte, data bytes and block end + // byte) dp->rxbuf[0] = msg->len + 3; - //block counter + // block counter dp->rxbuf[1] = dp->seq_nr; - //block title (service identification - SID) + // block title (service identification - SID) dp->rxbuf[2] = msg->type; - //data + // data memcpy(&dp->rxbuf[3], msg->data, msg->len); - //block end byte - dp->rxbuf[3+msg->len] = KWP1281_END_BYTE; + // block end byte + dp->rxbuf[3 + msg->len] = KWP1281_END_BYTE; dp->rxoffset = 0; - //time gap between messages - unsigned long long elapsed_time = diag_os_hrtus(diag_os_gethrt() - dp->msg_finish_time)/1000; - diag_os_millisleep(elapsed_time < KWP1281_T_RB_MIN ? KWP1281_T_RB_MIN-elapsed_time : 0); + // time gap between messages + unsigned long long elapsed_time = + diag_os_hrtus(diag_os_gethrt() - dp->msg_finish_time) / 1000; + diag_os_millisleep( + elapsed_time < KWP1281_T_RB_MIN ? KWP1281_T_RB_MIN - elapsed_time : 0); int retries = 0; - //send the block to the ECU + // send the block to the ECU while (1) { if (d_l2_conn->diag_link->l1flags & DIAG_L1_DOESL2FRAME) { - //for framed L0, must send the whole block at once - rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, dp->rxbuf, dp->rxbuf[0]+1, d_l2_conn->diag_l2_p4min); - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "after send, rv=%d\n", FL, - rv); + // for framed L0, must send the whole block at once + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, dp->rxbuf, + dp->rxbuf[0] + 1, d_l2_conn->diag_l2_p4min); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "after send, rv=%d\n", FL, rv); } if (rv < 0) { return diag_iseterr(rv); @@ -620,81 +681,92 @@ dl2p_vag_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { break; } - //send one byte at a time - rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, &dp->rxbuf[dp->rxoffset], 1, - d_l2_conn->diag_l2_p4min); + // send one byte at a time + rv = diag_l1_send(d_l2_conn->diag_link->l2_dl0d, 0, + &dp->rxbuf[dp->rxoffset], 1, d_l2_conn->diag_l2_p4min); unsigned long long byte_sent_time = diag_os_gethrt(); - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "after send, rv=%d rtoffset=%d\n", - FL, rv, dp->rxoffset); + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "after send, rv=%d rtoffset=%d\n", FL, rv, + dp->rxoffset); } if (rv < 0) { return diag_iseterr(rv); } - //have we just written the last byte? if so, then no inverted response will arrive + // have we just written the last byte? if so, then no inverted response + // will arrive if (dp->rxoffset == dp->rxbuf[0]) { dp->msg_finish_time = diag_os_gethrt(); break; } uint8_t recv_byte; - //ECU should respond with an inverted byte at most after t_r8 - rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &recv_byte, 1, KWP1281_T_R8); + // ECU should respond with an inverted byte at most after t_r8 + rv = diag_l1_recv(d_l2_conn->diag_link->l2_dl0d, 0, &recv_byte, 1, + KWP1281_T_R8); unsigned long long complement_recv_time = diag_os_gethrt(); - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "after recv, rv=%d\n", FL, rv); } if (rv < 0) { - //finish communication if exceeded the max number of retries or if some other error than timeout - if (++retries > KWP1281_TO_RETRIES || - rv != DIAG_ERR_TIMEOUT) { + // finish communication if exceeded the max number of retries or if + // some other error than timeout + if (++retries > KWP1281_TO_RETRIES || rv != DIAG_ERR_TIMEOUT) { return diag_iseterr(rv); } - //retry sending the message + // retry sending the message dp->rxoffset = 0; - //but only after another t_r8 - we must be sure that the receiver times-out - //so that it will expect a re-started message - elapsed_time = diag_os_hrtus(diag_os_gethrt() - byte_sent_time)/1000; - diag_os_millisleep(elapsed_time < 2*KWP1281_T_R8 ? 2*KWP1281_T_R8-elapsed_time : 0); + // but only after another t_r8 - we must be sure that the receiver + // times-out so that it will expect a re-started message + elapsed_time = + diag_os_hrtus(diag_os_gethrt() - byte_sent_time) / 1000; + diag_os_millisleep(elapsed_time < 2 * KWP1281_T_R8 + ? 2 * KWP1281_T_R8 - elapsed_time + : 0); continue; } - //check the received byte + // check the received byte uint8_t complement = ~dp->rxbuf[dp->rxoffset]; if (recv_byte != complement) { - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "Received incorrect inverted byte: " "0x%.2X (expected 0x%.2X)\n", FL, (int)recv_byte, (int)complement); } - //finish communication if exceeded the max number of retries + // finish communication if exceeded the max number of retries if (++retries > KWP1281_TO_RETRIES) { return diag_iseterr(DIAG_ERR_BADCSUM); } - //retry sending the message + // retry sending the message dp->rxoffset = 0; - //but only after another t_r8 - we must be sure that the receiver times-out - //so that it will expect a re-started message - elapsed_time = diag_os_hrtus(diag_os_gethrt() - byte_sent_time)/1000; - diag_os_millisleep(elapsed_time < 2*KWP1281_T_R8 ? 2*KWP1281_T_R8-elapsed_time : 0); + // but only after another t_r8 - we must be sure that the receiver + // times-out so that it will expect a re-started message + elapsed_time = + diag_os_hrtus(diag_os_gethrt() - byte_sent_time) / 1000; + diag_os_millisleep(elapsed_time < 2 * KWP1281_T_R8 + ? 2 * KWP1281_T_R8 - elapsed_time + : 0); continue; } dp->rxoffset++; - //how much time elapsed since receiving a correct complement byte? - elapsed_time = diag_os_hrtus(diag_os_gethrt() - complement_recv_time)/1000; - //give ECU some time before sending next byte - diag_os_millisleep(elapsed_time < KWP1281_T_R6_MIN ? KWP1281_T_R6_MIN-elapsed_time : 0); + // how much time elapsed since receiving a correct complement byte? + elapsed_time = + diag_os_hrtus(diag_os_gethrt() - complement_recv_time) / 1000; + // give ECU some time before sending next byte + diag_os_millisleep(elapsed_time < KWP1281_T_R6_MIN + ? KWP1281_T_R6_MIN - elapsed_time + : 0); } - //we are slave now + // we are slave now dp->master = 0; return 0; @@ -705,11 +777,10 @@ dl2p_vag_send(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg) { */ static int dl2p_vag_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, - void (*callback)(void *handle, struct diag_msg *msg), - void *handle) { + void (*callback)(void *handle, struct diag_msg *msg), void *handle) { int rv; - if (diag_l2_debug & DIAG_DEBUG_PROTO && timeout != 0) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO && timeout != 0) { fprintf(stderr, FLFMT "WARNING! l2_vag will ignore the given timeout! (%d " @@ -717,44 +788,44 @@ dl2p_vag_recv(struct diag_l2_conn *d_l2_conn, unsigned int timeout, FL, timeout); } - //if it is the first call to the recv() function since startcomms, then - //the message (ECU ID telegram) is already read, so call int_recv() only if the little shiny present - //has already been collected + // if it is the first call to the recv() function since startcomms, then + // the message (ECU ID telegram) is already read, so call int_recv() only if the + // little shiny present has already been collected struct diag_l2_vag *dp = (struct diag_l2_vag *)d_l2_conn->diag_l2_proto_data; if (dp->ecu_id_telegram == NULL) { - //call the internal routine + // call the internal routine rv = diag_l2_vag_int_recv(d_l2_conn, KWP1281_T_RB_MAX); if (rv < 0) { return rv; } } else { - //int_recv() also does this + // int_recv() also does this if (d_l2_conn->diag_msg) { diag_freemsg(d_l2_conn->diag_msg); d_l2_conn->diag_msg = NULL; } - //copy the ECU ID telegram address + // copy the ECU ID telegram address d_l2_conn->diag_msg = dp->ecu_id_telegram; - //and make sure the pointer is no more + // and make sure the pointer is no more dp->ecu_id_telegram = NULL; } - if (diag_l2_debug & DIAG_DEBUG_READ) { - fprintf(stderr, FLFMT "calling rcv callback, handle=%p\n", FL, - handle); + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "calling rcv callback, handle=%p\n", FL, handle); } - //Call user callback routine - //NOTE: if ECU returned NO_ACK, then the caller won't know what type it was (retry or unknown) + // Call user callback routine + // NOTE: if ECU returned NO_ACK, then the caller won't know what type it was (retry + // or unknown) if (callback) { callback(handle, d_l2_conn->diag_msg); } - //Message no longer needed + // Message no longer needed diag_freemsg(d_l2_conn->diag_msg); d_l2_conn->diag_msg = NULL; - if (diag_l2_debug & DIAG_DEBUG_READ) { + if (diag_l2_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "rcv callback completed\n", FL); } @@ -768,37 +839,35 @@ dl2p_vag_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errv struct diag_l2_vag *dp = (struct diag_l2_vag *)d_l2_conn->diag_l2_proto_data; while (1) { - //send the request + // send the request rv = diag_l2_send(d_l2_conn, msg); if (rv < 0) { *errval = rv; return diag_pseterr(rv); } - //and receive the response telegram + // and receive the response telegram rv = diag_l2_vag_int_recv(d_l2_conn, KWP1281_T_RB_MAX); if (rv < 0) { *errval = rv; return diag_pseterr(rv); } - //if it isn't No Acknowledge - Retry, then ok + // if it isn't No Acknowledge - Retry, then ok if (d_l2_conn->diag_msg->type != KWP1281_SID_NO_ACK || d_l2_conn->diag_msg->data[0] != dp->seq_nr - 2) { break; } - //but if it is, then we will repeat the request - if (diag_l2_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, - FLFMT - "Received No Acknowledge - Retry message\n", + // but if it is, then we will repeat the request + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "Received No Acknowledge - Retry message\n", FL); } - //accept at most KWP1281_NA_RETRIES of No Ack Retry messages in a row + // accept at most KWP1281_NA_RETRIES of No Ack Retry messages in a row if (++na_retry_cnt == KWP1281_NA_RETRIES) { - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "\tbut too many Retry messages in a " @@ -808,22 +877,25 @@ dl2p_vag_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errv *errval = DIAG_ERR_ECUSAIDNO; return diag_pseterr(*errval); } - if (diag_l2_debug & DIAG_DEBUG_PROTO) { + if (diag_l2_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "\tso will retry\n", FL); } - //re-send with the previous sequence number - //NOTE: SAE J2818 says that "The Message number is NOT incremented by the transmitter for a repeated block." - // so we should send the repeated message with the same sequence number as the original message. - // However, when testing this on an ECU installed in a European VW the ECU didn't accept such a message - // (responded with another NO_ACK Retry) and a repeated message with an incremented sequence number - // was accepted. - // Can't test this with a VW from USA, so commenting-out for now. If US VWs indeed follow the specification - // strictly, then a possible solution would be to set/unset this behaviour based on a flag - // (eg. L2_vag specific option for enabling/disabling strict SAE J2818). - //dp->seq_nr -= 2; + // re-send with the previous sequence number + // NOTE: SAE J2818 says that "The Message number is NOT incremented by the + // transmitter for a repeated block." + // so we should send the repeated message with the same sequence + // number as the original message. However, when testing this on an + // ECU installed in a European VW the ECU didn't accept such a message + // (responded with another NO_ACK Retry) and a repeated message with + // an incremented sequence number was accepted. Can't test this with a + // VW from USA, so commenting-out for now. If US VWs indeed follow the + // specification strictly, then a possible solution would be to + // set/unset this behaviour based on a flag (eg. L2_vag specific + // option for enabling/disabling strict SAE J2818). + // dp->seq_nr -= 2; } - //now it's the requester's responsibility to take care of the telegram + // now it's the requester's responsibility to take care of the telegram rmsg = d_l2_conn->diag_msg; d_l2_conn->diag_msg = NULL; @@ -840,21 +912,20 @@ dl2p_vag_timeout(struct diag_l2_conn *d_l2_conn) { memset(&ack, 0, sizeof(ack)); ack.type = KWP1281_SID_ACK; - if (diag_l2_debug & DIAG_DEBUG_TIMER) { - fprintf(stderr, FLFMT "timeout impending for %p\n", FL, - (void *)d_l2_conn); + if (diag_l2_debug_load() & DIAG_DEBUG_TIMER) { + fprintf(stderr, FLFMT "timeout impending for %p\n", FL, (void *)d_l2_conn); } - //store the ECU ID address, so that the telegram won't get deleted by send() + // store the ECU ID address, so that the telegram won't get deleted by send() //(we don't want it to happen because of the keep-alive exchange) struct diag_l2_vag *dp = (struct diag_l2_vag *)d_l2_conn->diag_l2_proto_data; struct diag_msg *ecu_id_telegram = dp->ecu_id_telegram; dp->ecu_id_telegram = NULL; - //Send the ACK message; important to use l2_send as it updates the timers + // Send the ACK message; important to use l2_send as it updates the timers int rv = diag_l2_send(d_l2_conn, &ack); if (rv < 0) { - if (diag_l2_debug & DIAG_DEBUG_TIMER) { + if (diag_l2_debug_load() & DIAG_DEBUG_TIMER) { fprintf(stderr, FLFMT "KW1281 send keep-alive failed with the " @@ -864,10 +935,10 @@ dl2p_vag_timeout(struct diag_l2_conn *d_l2_conn) { return; } - //we don't have to worry about ECU responding NoAck - it's just a keep-alive exchange - //so it's ok as long as neither side timeouts + // we don't have to worry about ECU responding NoAck - it's just a keep-alive + // exchange so it's ok as long as neither side timeouts rv = diag_l2_recv(d_l2_conn, 0, NULL, NULL); - if (rv < 0 && diag_l2_debug & DIAG_DEBUG_TIMER) { + if (rv < 0 && diag_l2_debug_load() & DIAG_DEBUG_TIMER) { fprintf(stderr, FLFMT "KW1281 receive keep-alive failed with the following " @@ -875,18 +946,11 @@ dl2p_vag_timeout(struct diag_l2_conn *d_l2_conn) { FL, diag_errlookup(rv)); } - //copy the ECU ID telegram address back where it belongs + // copy the ECU ID telegram address back where it belongs dp->ecu_id_telegram = ecu_id_telegram; } const struct diag_l2_proto diag_l2_proto_vag = { - DIAG_L2_PROT_VAG, - "VAG", - DIAG_L2_FLAG_KEEPALIVE, - dl2p_vag_startcomms, - dl2p_vag_stopcomms, - dl2p_vag_send, - dl2p_vag_recv, - dl2p_vag_request, - dl2p_vag_timeout -}; + DIAG_L2_PROT_VAG, "VAG", DIAG_L2_FLAG_KEEPALIVE, dl2p_vag_startcomms, + dl2p_vag_stopcomms, dl2p_vag_send, dl2p_vag_recv, dl2p_vag_request, + dl2p_vag_timeout}; diff --git a/scantool/diag_l2_vag.h b/scantool/diag_l2_vag.h index ee2aee25..ab412ecc 100644 --- a/scantool/diag_l2_vag.h +++ b/scantool/diag_l2_vag.h @@ -37,39 +37,48 @@ extern "C" { #define KWP1281_KW_BYTE_1 0x01 #define KWP1281_KW_BYTE_2 0x8A -#define KWP1281_END_BYTE 0x03 +#define KWP1281_END_BYTE 0x03 -//Initialization-specific times -#define KWP1281_T_R0 300 //before 5baud Initialization Byte (Scan Tool -> ECU) -#define KWP1281_T_R1_MIN 80 //between Init Byte and Synchronization Byte (ECU -> Scan Tool) -#define KWP1281_T_R1_MAX 210 -#define KWP1281_T_R2_MIN 5 //time between Sync Byte and KW1 Byte (ECU -> Scan Tool) -#define KWP1281_T_R2_MAX 50 // (KWP1281_T_R2_MAX is relaxed from standard) -#define KWP1281_T_R3_MIN 1 //time between KW1 and KW2 Byte (ECU -> Scan Tool) -#define KWP1281_T_R3_MAX 20 -#define KWP1281_T_R4_MIN 25 //time between KW2 Byte and KW2 Complement (Scan Tool -> ECU) -#define KWP1281_T_R4_MAX 50 -//After initialization -#define KWP1281_T_R5_MIN 25 //time between KW2 Complement and 1st ECU message (ECU -> Scan Tool) -#define KWP1281_T_R5_MAX 50 -#define KWP1281_T_RK 231 //time ECU waits before re-sending the Sync Byte if KW2 Complement was incorrect (ECU -> Scan Tool) -//Communication-specific times -#define KWP1281_T_R6_MIN 1 //time Scan Tool waits before sending next byte to ECU -#define KWP1281_T_R6_MAX 50 -#define KWP1281_T_R7_MIN 1 //time ECU waits before sending next byte to Scan Tool this is 0.5ms, actually... -#define KWP1281_T_R7_MAX 50 -#define KWP1281_T_R8 55 //timeout while waiting for a message byte (ECU and Scan Tool; R6_MAX+5 or R7_MAX+5) -#define KWP1281_T_RB_MIN 1 //time between messages (ECU and Scan Tool) -#define KWP1281_T_RB 1000 -#define KWP1281_T_RB_MAX 1100 +// Initialization-specific times +#define KWP1281_T_R0 300 // before 5baud Initialization Byte (Scan Tool -> ECU) +#define KWP1281_T_R1_MIN \ + 80 // between Init Byte and Synchronization Byte (ECU -> Scan + // Tool) +#define KWP1281_T_R1_MAX 210 +#define KWP1281_T_R2_MIN 5 // time between Sync Byte and KW1 Byte (ECU -> Scan Tool) +#define KWP1281_T_R2_MAX 50 // (KWP1281_T_R2_MAX is relaxed from standard) +#define KWP1281_T_R3_MIN 1 // time between KW1 and KW2 Byte (ECU -> Scan Tool) +#define KWP1281_T_R3_MAX 20 +#define KWP1281_T_R4_MIN 25 // time between KW2 Byte and KW2 Complement (Scan Tool -> ECU) +#define KWP1281_T_R4_MAX 50 +// After initialization +#define KWP1281_T_R5_MIN \ + 25 // time between KW2 Complement and 1st ECU message (ECU -> Scan Tool) +#define KWP1281_T_R5_MAX 50 +#define KWP1281_T_RK \ + 231 // time ECU waits before re-sending the Sync Byte if KW2 Complement was + // incorrect (ECU -> Scan Tool) +// Communication-specific times +#define KWP1281_T_R6_MIN 1 // time Scan Tool waits before sending next byte to ECU +#define KWP1281_T_R6_MAX 50 +#define KWP1281_T_R7_MIN \ + 1 // time ECU waits before sending next byte to Scan Tool this is 0.5ms, + // actually... +#define KWP1281_T_R7_MAX 50 +#define KWP1281_T_R8 \ + 55 // timeout while waiting for a message byte (ECU and Scan Tool; R6_MAX+5 or + // R7_MAX+5) +#define KWP1281_T_RB_MIN 1 // time between messages (ECU and Scan Tool) +#define KWP1281_T_RB 1000 +#define KWP1281_T_RB_MAX 1100 // -#define KWP1281_NA_RETRIES 5 //number of No Ack retries before a message is discarded -#define KWP1281_TO_RETRIES 3 //number of time-out retries before a message is discarded +#define KWP1281_NA_RETRIES 5 // number of No Ack retries before a message is discarded +#define KWP1281_TO_RETRIES 3 // number of time-out retries before a message is discarded -#define KWP1281_SID_ACK 0x09 -#define KWP1281_SID_NO_ACK 0x0A +#define KWP1281_SID_ACK 0x09 +#define KWP1281_SID_NO_ACK 0x0A #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L2_VAG_H_ */ diff --git a/scantool/diag_l3.c b/scantool/diag_l3.c index 641d0d6d..20f05da9 100644 --- a/scantool/diag_l3.c +++ b/scantool/diag_l3.c @@ -38,10 +38,45 @@ #include "utlist.h" -int diag_l3_debug; +DIAG_ATOMIC_STATICALLY_DECL_INIT(static diag_atomic_int diag_l3_debug) +void +diag_l3_debug_store(int d) { + diag_atomic_store_int(&diag_l3_debug, d); +} +int +diag_l3_debug_load(void) { + return diag_atomic_load_int(&diag_l3_debug); +} + +static diag_mtx connlist_mtx = LOCK_INITIALIZER; +static struct diag_l3_conn *diag_l3_list; +static bool init_done; + +void +diag_l3_init(void) { + if (init_done) { + return; + } + + DIAG_ATOMIC_INITSTATIC(&diag_l3_debug); -static struct diag_l3_conn *diag_l3_list; + if (diag_l3_debug_load() & DIAG_DEBUG_INIT) { + fprintf(stderr, FLFMT "entered diag_l3_init\n", FL); + } + diag_os_initstaticmtx(&connlist_mtx); + + init_done = true; + return; +} + +void +diag_l3_end(void) { + diag_os_delmtx(&connlist_mtx); + DIAG_ATOMIC_DEL(&diag_l3_debug); + init_done = false; + return; +} struct diag_l3_conn * diag_l3_start(const char *protocol, struct diag_l2_conn *d_l2_conn) { @@ -52,22 +87,22 @@ diag_l3_start(const char *protocol, struct diag_l2_conn *d_l2_conn) { assert(d_l2_conn != NULL); - if (diag_l3_debug & DIAG_DEBUG_OPEN) { + if (diag_l3_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "start protocol %s l2 %p\n", FL, protocol, (void *)d_l2_conn); } /* Find the protocol */ dp = NULL; - for (i=0; diag_l3_protocols[i]; i++) { + for (i = 0; diag_l3_protocols[i]; i++) { if (strcasecmp(protocol, diag_l3_protocols[i]->proto_name) == 0) { - dp = diag_l3_protocols[i]; /* Found. */ + dp = diag_l3_protocols[i]; /* Found. */ break; } } if (dp) { - if (diag_l3_debug & DIAG_DEBUG_OPEN) { + if (diag_l3_debug_load() & DIAG_DEBUG_OPEN) { fprintf(stderr, FLFMT "start protocol %s found\n", FL, dp->proto_name); } @@ -83,14 +118,12 @@ diag_l3_start(const char *protocol, struct diag_l2_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); + (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); + (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); @@ -101,25 +134,25 @@ diag_l3_start(const char *protocol, struct diag_l2_conn *d_l2_conn) { /* * Set time to now */ - d_l3_conn->timer=diag_os_getms(); + d_l3_conn->timer = diag_os_getms(); /* * And add to list */ + diag_os_lock(&connlist_mtx); LL_PREPEND(diag_l3_list, d_l3_conn); - + diag_os_unlock(&connlist_mtx); } - if (diag_l3_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "start returns %p\n", FL, - (void *)d_l3_conn); + if (diag_l3_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "start returns %p\n", FL, (void *)d_l3_conn); } return d_l3_conn; } - -int diag_l3_stop(struct diag_l3_conn *d_l3_conn) { +int +diag_l3_stop(struct diag_l3_conn *d_l3_conn) { int rv; assert(d_l3_conn != NULL); @@ -133,10 +166,11 @@ int diag_l3_stop(struct diag_l3_conn *d_l3_conn) { free(d_l3_conn); - return rv? diag_iseterr(rv):0; + return rv ? diag_iseterr(rv) : 0; } -int diag_l3_send(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg) { +int +diag_l3_send(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg) { int rv; const struct diag_l3_proto *dp = d_l3_conn->d_l3_proto; @@ -146,16 +180,16 @@ int diag_l3_send(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg) { d_l3_conn->timer = diag_os_getms(); } - return rv? diag_iseterr(rv):0; + return rv ? diag_iseterr(rv) : 0; } -int diag_l3_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, - void (* rcv_call_back)(void *handle ,struct diag_msg *) , void *handle) { +int +diag_l3_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, + void (*rcv_call_back)(void *handle, struct diag_msg *), void *handle) { const struct diag_l3_proto *dp = d_l3_conn->d_l3_proto; int rv; - rv=dp->diag_l3_proto_recv(d_l3_conn, timeout, - rcv_call_back, handle); + rv = dp->diag_l3_proto_recv(d_l3_conn, timeout, rcv_call_back, handle); if (rv == 0) { d_l3_conn->timer = diag_os_getms(); @@ -164,20 +198,20 @@ int diag_l3_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, if (rv == DIAG_ERR_TIMEOUT) { return rv; } - return rv? diag_iseterr(rv):0; + return rv ? diag_iseterr(rv) : 0; } - -void diag_l3_decode(struct diag_l3_conn *d_l3_conn, - struct diag_msg *msg, char *buf, const size_t bufsize) { +void +diag_l3_decode(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg, char *buf, + const size_t bufsize) { const struct diag_l3_proto *dp = d_l3_conn->d_l3_proto; dp->diag_l3_proto_decode(d_l3_conn, msg, buf, bufsize); return; } - -int diag_l3_ioctl(struct diag_l3_conn *d_l3_conn, unsigned int cmd, void *data) { +int +diag_l3_ioctl(struct diag_l3_conn *d_l3_conn, unsigned int cmd, void *data) { const struct diag_l3_proto *dp = d_l3_conn->d_l3_proto; /* Call the L3 ioctl routine if applicable */ @@ -189,15 +223,14 @@ int diag_l3_ioctl(struct diag_l3_conn *d_l3_conn, unsigned int cmd, void *data) return diag_l2_ioctl(d_l3_conn->d_l3l2_conn, cmd, data); } - struct diag_msg * diag_l3_request(struct diag_l3_conn *dl3c, struct diag_msg *txmsg, int *errval) { struct diag_msg *rxmsg; const struct diag_l3_proto *dl3p = dl3c->d_l3_proto; - if (diag_l3_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "_request dl3c=%p msg=%p called\n", FL, - (void *)dl3c, (void *)txmsg); + if (diag_l3_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "_request dl3c=%p msg=%p called\n", FL, (void *)dl3c, + (void *)txmsg); } /* Call protocol specific send routine */ @@ -207,15 +240,15 @@ diag_l3_request(struct diag_l3_conn *dl3c, struct diag_msg *txmsg, int *errval) rxmsg = NULL; } - if (diag_l3_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "_request returns %p, err %d\n", - FL, (void *)rxmsg, *errval); + if (diag_l3_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "_request returns %p, err %d\n", FL, (void *)rxmsg, + *errval); } - if (rxmsg==NULL) { + if (rxmsg == NULL) { return diag_pseterr(*errval); } - //update timers + // update timers dl3c->timer = diag_os_getms(); return rxmsg; @@ -226,20 +259,24 @@ diag_l3_request(struct diag_l3_conn *dl3c, struct diag_msg *txmsg, int *errval) * (see diag_os.c) * XXX This calls non async-signal-safe functions! */ - -void diag_l3_timer(void) { +void +diag_l3_timer(void) { /* * Regular timer routine * Call protocol specific timer */ struct diag_l3_conn *conn; - unsigned long now=diag_os_getms(); + unsigned long now = diag_os_getms(); + + if (periodic_done() || !diag_os_trylock(&connlist_mtx)) { + return; + } LL_FOREACH(diag_l3_list, conn) { /* Call L3 timer routine for this connection */ const struct diag_l3_proto *dp = conn->d_l3_proto; - //skip connection if L1 does the keepalive stuff + // skip connection if L1 does the keepalive stuff if (conn->d_l3l1_flags & DIAG_L1_DOESKEEPALIVE) { continue; } @@ -249,56 +286,54 @@ void diag_l3_timer(void) { diffms = now - conn->timer; - (void) dp->diag_l3_proto_timer(conn, diffms); + (void)dp->diag_l3_proto_timer(conn, diffms); } } + diag_os_unlock(&connlist_mtx); } - /* Base implementations for some functions */ - -int diag_l3_base_start(UNUSED(struct diag_l3_conn *d_l3_conn)) { +int +diag_l3_base_start(UNUSED(struct diag_l3_conn *d_l3_conn)) { return 0; } - -int diag_l3_base_stop(UNUSED(struct diag_l3_conn *d_l3_conn)) { +int +diag_l3_base_stop(UNUSED(struct diag_l3_conn *d_l3_conn)) { return 0; } -int diag_l3_base_send(struct diag_l3_conn *d_l3_conn, - UNUSED(struct diag_msg *msg)) { - d_l3_conn->timer=diag_os_getms(); +int +diag_l3_base_send(struct diag_l3_conn *d_l3_conn, UNUSED(struct diag_msg *msg)) { + d_l3_conn->timer = diag_os_getms(); return 0; } - int -diag_l3_base_recv(struct diag_l3_conn *d_l3_conn, - UNUSED(unsigned int timeout), - UNUSED(void (* rcv_call_back)(void *handle ,struct diag_msg *)), - UNUSED(void *handle)) { - d_l3_conn->timer=diag_os_getms(); +diag_l3_base_recv(struct diag_l3_conn *d_l3_conn, UNUSED(unsigned int timeout), + UNUSED(void (*rcv_call_back)(void *handle, struct diag_msg *)), + UNUSED(void *handle)) { + d_l3_conn->timer = diag_os_getms(); return 0; } -//this implementation is rather naive and untested. It simply forwards the -//txmsg straight to the L2 request function and returns the response msg -//as-is. -struct diag_msg *diag_l3_base_request(struct diag_l3_conn *dl3c, - struct diag_msg *txmsg, int *errval) { +// this implementation is rather naive and untested. It simply forwards the +// txmsg straight to the L2 request function and returns the response msg +// as-is. +struct diag_msg * +diag_l3_base_request(struct diag_l3_conn *dl3c, struct diag_msg *txmsg, int *errval) { struct diag_msg *rxmsg = NULL; - *errval=0; + *errval = 0; rxmsg = diag_l2_request(dl3c->d_l3l2_conn, txmsg, errval); if (rxmsg == NULL) { return diag_pseterr(*errval); } - dl3c->timer=diag_os_getms(); + dl3c->timer = diag_os_getms(); return rxmsg; } diff --git a/scantool/diag_l3.h b/scantool/diag_l3.h index 9e3500c1..f0811fc3 100644 --- a/scantool/diag_l3.h +++ b/scantool/diag_l3.h @@ -37,26 +37,26 @@ struct diag_msg; /** Layer 3 connection info */ struct diag_l3_conn { - struct diag_l2_conn *d_l3l2_conn; - int d_l3l2_flags; /* Flags from L2 */ - uint32_t d_l3l1_flags; /* Flags from L1 */ + struct diag_l2_conn *d_l3l2_conn; + int d_l3l2_flags; /* Flags from L2 */ + uint32_t d_l3l1_flags; /* Flags from L1 */ const struct diag_l3_proto *d_l3_proto; - void *l3_int; // internal (private) data for each connection instance + void *l3_int; // internal (private) data for each connection instance /* Callback into next layer (which passed us the handle) */ void (*callback)(void *handle, struct diag_msg *msg); void *handle; /* Received messages */ - struct diag_msg *msg; + struct diag_msg *msg; - /* time (in ms since an arbitrary reference) of last tx/rx , for managing periodic timers */ + /* time (in ms since an arbitrary reference) of last tx/rx , for managing periodic + * timers */ unsigned long timer; /* Linked list held by main L3 code */ - struct diag_l3_conn *next; - + struct diag_l3_conn *next; }; /** L3 Protocol descriptor. @@ -70,29 +70,30 @@ struct diag_l3_conn { struct diag_l3_proto { const char *proto_name; - //start, stop : initiate L3 comms, filling the given diag_l3_conn. Must return 0 if ok, <0 on error + // start, stop : initiate L3 comms, filling the given diag_l3_conn. Must return 0 + // if ok, <0 on error int (*diag_l3_proto_start)(struct diag_l3_conn *); int (*diag_l3_proto_stop)(struct diag_l3_conn *); - //proto_send: ret 0 if ok + // proto_send: ret 0 if ok int (*diag_l3_proto_send)(struct diag_l3_conn *, struct diag_msg *); - //proto_recv: ret 0 if ok + // proto_recv: ret 0 if ok int (*diag_l3_proto_recv)(struct diag_l3_conn *, unsigned int, - void (* rcv_call_back)(void *handle ,struct diag_msg *) , void *); + void (*rcv_call_back)(void *handle, struct diag_msg *), + void *); - //proto_ioctl (optional). ret 0 if ok; if not defined the ioctl is passed to L2. + // proto_ioctl (optional). ret 0 if ok; if not defined the ioctl is passed to L2. int (*diag_l3_proto_ioctl)(struct diag_l3_conn *, int cmd, void *data); - //proto_request : send request and return a new message with the reply, and error in *errval (0 if ok) + // proto_request : send request and return a new message with the reply, and error + // in *errval (0 if ok) struct diag_msg *(*diag_l3_proto_request)(struct diag_l3_conn *, - struct diag_msg *txmsg, int *errval); + struct diag_msg *txmsg, int *errval); /* Decode msg to printable text in *buf */ - void (*diag_l3_proto_decode)(struct diag_l3_conn *, - struct diag_msg *msg, - char *buf, - const size_t bufsize); + void (*diag_l3_proto_decode)(struct diag_l3_conn *, struct diag_msg *msg, + char *buf, const size_t bufsize); /* Timer (optional) * If defined, this is called from diag_l3_timer() @@ -101,9 +102,17 @@ struct diag_l3_proto { * ret 0 if ok */ int (*diag_l3_proto_timer)(struct diag_l3_conn *, unsigned long ms); - }; +/** Initialize L3 layer + * Must be called once before using any L3 function + */ +void diag_l3_init(void); + +/** De-initialize L3 layer + * opposite of diag_l3_init(); call before unloading / exiting + */ +void diag_l3_end(void); /** Start L3 connection * @@ -118,33 +127,33 @@ struct diag_l3_conn *diag_l3_start(const char *protocol, struct diag_l2_conn *d_ * must free() everything diag_l3_start alloc'd * and remove from diag_l3_list */ -int diag_l3_stop(struct diag_l3_conn *d_l3_conn); +int diag_l3_stop(struct diag_l3_conn *d_l3_conn); /** Send message * * @return 0 if ok */ -int diag_l3_send(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg); +int diag_l3_send(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg); /** Receive message * * @return 0 if ok */ -int diag_l3_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, - void (* rcv_call_back)(void *handle ,struct diag_msg *) , void *handle); +int diag_l3_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, + void (*rcv_call_back)(void *handle, struct diag_msg *), void *handle); /** Format given message as text * */ -void diag_l3_decode(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg, - char *buf, const size_t bufsize); +void diag_l3_decode(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg, char *buf, + const size_t bufsize); /** Send a request and return a new msg with the response. * * Caller must free that msg */ -struct diag_msg *diag_l3_request(struct diag_l3_conn *dl3c, struct diag_msg *txmsg, - int *errval); +struct diag_msg * +diag_l3_request(struct diag_l3_conn *dl3c, struct diag_msg *txmsg, int *errval); /** Send ioctl to the specified * L3 @@ -161,7 +170,6 @@ int diag_l3_ioctl(struct diag_l3_conn *connection, unsigned int cmd, void *data) */ void diag_l3_timer(void); - /* Base implementations: * these are defined in diag_l3.c and perform no operation. */ @@ -169,16 +177,16 @@ int diag_l3_base_start(struct diag_l3_conn *); int diag_l3_base_stop(struct diag_l3_conn *); int diag_l3_base_send(struct diag_l3_conn *, struct diag_msg *); int diag_l3_base_recv(struct diag_l3_conn *, unsigned int, - void (* rcv_call_back)(void *handle ,struct diag_msg *) , void *); -//XXX diag_l3_base_ioctl : there's no code for this one ? -//int diag_l3_base_ioctl(struct diag_l3_conn *, int cmd, void *data); -struct diag_msg *diag_l3_base_request(struct diag_l3_conn *dl3c, - struct diag_msg *txmsg, int *errval); - - + void (*rcv_call_back)(void *handle, struct diag_msg *), void *); +// XXX diag_l3_base_ioctl : there's no code for this one ? +// int diag_l3_base_ioctl(struct diag_l3_conn *, int cmd, void *data); +struct diag_msg * +diag_l3_base_request(struct diag_l3_conn *dl3c, struct diag_msg *txmsg, int *errval); // diag_l3_debug : contains debugging message flags (see diag.h) -extern int diag_l3_debug; +void diag_l3_debug_store(int d); +int diag_l3_debug_load(void); + extern struct diag_l3_conn *global_l3_conn; /* List of supported L3 protocols; last element is NULL */ @@ -186,5 +194,5 @@ extern const struct diag_l3_proto *diag_l3_protocols[]; #if defined(__cplusplus) } -#endif +# endif #endif diff --git a/scantool/diag_l3_iso14230.c b/scantool/diag_l3_iso14230.c index 22f09a3f..3270978c 100644 --- a/scantool/diag_l3_iso14230.c +++ b/scantool/diag_l3_iso14230.c @@ -37,12 +37,9 @@ #include "diag_l3.h" #include "diag_l3_iso14230.h" - - static const char *l3_iso14230_sidlookup(const int id); static const char *l3_iso14230_neglookup(const int id); - /* * We'll use a big switch statement here, and rely on the compiler * to make it efficient @@ -50,12 +47,11 @@ static const char *l3_iso14230_neglookup(const int id); * is the service ID byte. */ char * -diag_l3_iso14230_decode_response(struct diag_msg *msg, - char *buf, const size_t bufsize) { +diag_l3_iso14230_decode_response(struct diag_msg *msg, char *buf, const size_t bufsize) { char buf2[80]; switch (msg->data[0]) { - //for these 3 SID's, + // for these 3 SID's, case DIAG_KW2K_RC_SCRPR: snprintf(buf, bufsize, "StartCommunications_OK"); break; @@ -68,46 +64,49 @@ diag_l3_iso14230_decode_response(struct diag_msg *msg, case DIAG_KW2K_RC_NR: if (msg->len < 3) { - snprintf(buf, bufsize, "General_Error, no response code"); + snprintf(buf, bufsize, "General_Error, no response code"); } else { - snprintf(buf, bufsize, "General_Error, Requested_SID_%s ", - l3_iso14230_sidlookup(msg->data[1])); + snprintf(buf, bufsize, "General_Error, Requested_SID_%s ", + l3_iso14230_sidlookup(msg->data[1])); snprintf(buf2, sizeof(buf2), "Error_%s", - l3_iso14230_neglookup(msg->data[2])); + l3_iso14230_neglookup(msg->data[2])); /* Don't overflow our buffers. */ - smartcat(buf, bufsize, buf2 ); + smartcat(buf, bufsize, buf2); } break; default: - //data[0] is either a "positive response service identifier (SNPR)" - //or a NACK (0x7F); which we already checked... bit 6 is set on all + // data[0] is either a "positive response service identifier (SNPR)" + // or a NACK (0x7F); which we already checked... bit 6 is set on all // positive responses (14230-3 table 1) if (msg->data[0] & 0x40) { snprintf(buf, bufsize, "Positive response, %s ", - l3_iso14230_sidlookup(msg->data[0] & ~0x40)); + l3_iso14230_sidlookup(msg->data[0] & ~0x40)); switch (msg->data[0] & ~0x40) { - case DIAG_KW2K_SI_REID: - snprintf(buf2, sizeof(buf2), "identOption 0x%02X", msg->data[1]); - smartcat(buf, bufsize, buf2); - break; - case DIAG_KW2K_SI_RDDBLI: - snprintf(buf2, sizeof(buf2), "RLOCID 0x%02X", msg->data[1]); - smartcat(buf, bufsize, buf2); - break; - default: - break; + case DIAG_KW2K_SI_REID: + snprintf(buf2, sizeof(buf2), "identOption 0x%02X", + msg->data[1]); + smartcat(buf, bufsize, buf2); + break; + case DIAG_KW2K_SI_RDDBLI: + snprintf(buf2, sizeof(buf2), "RLOCID 0x%02X", + msg->data[1]); + smartcat(buf, bufsize, buf2); + break; + default: + break; } - //TODO : add "custom" printout for every SID that has a local ID ? - //or maybe expand the SID tables to include a field that indicates how many - //extra bytes are meaningful. For example, SID 27 SecurityAccess + // TODO : add "custom" printout for every SID that has a local ID ? + // or maybe expand the SID tables to include a field that indicates + // how many extra bytes are meaningful. For example, SID 27 + // SecurityAccess } else { snprintf(buf, bufsize, "Unknown_response_code 0x%02X", - msg->data[0]); + msg->data[0]); } break; } @@ -115,13 +114,12 @@ diag_l3_iso14230_decode_response(struct diag_msg *msg, return buf; } - -//return 0 if ok. -//the data in *msg should have no headers and no checksum, obviously. -//address information should be already set as well; this function just -//forwards the request to l2_send (presumably the user is using this L3 -//proto over an iso14230 L2 proto. Running an iso14230 L3 over anything other -//than iso14230 is meaningless. +// return 0 if ok. +// the data in *msg should have no headers and no checksum, obviously. +// address information should be already set as well; this function just +// forwards the request to l2_send (presumably the user is using this L3 +// proto over an iso14230 L2 proto. Running an iso14230 L3 over anything other +// than iso14230 is meaningless. static int diag_l3_iso14230_send(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg) { int rv; @@ -130,24 +128,22 @@ diag_l3_iso14230_send(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg) { /* Get l2 connection info */ d_conn = d_l3_conn->d_l3l2_conn; - if (diag_l3_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr,FLFMT "_send %d bytes, l2 flags 0x%X\n", - FL, msg->len, d_l3_conn->d_l3l2_flags); + if (diag_l3_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "_send %d bytes, l2 flags 0x%X\n", FL, msg->len, + d_l3_conn->d_l3l2_flags); - if ((diag_l3_debug & DIAG_DEBUG_DATA) && - (diag_l3_debug & DIAG_DEBUG_WRITE)) { - diag_data_dump(stderr, (void *)msg->data, - (size_t)msg->len); + if ((diag_l3_debug_load() & DIAG_DEBUG_DATA) && + (diag_l3_debug_load() & DIAG_DEBUG_WRITE)) { + diag_data_dump(stderr, (void *)msg->data, (size_t)msg->len); } } // L2 does framing, adds addressing and CRC, so do nothing special rv = diag_l2_send(d_conn, msg); - return rv? diag_iseterr(rv):0 ; + return rv ? diag_iseterr(rv) : 0; } - /* * RX callback, called as data received from L2 (from l3_recv). If we get a full message, * call L3 callback routine @@ -161,13 +157,13 @@ diag_l3_14230_rxcallback(void *handle, struct diag_msg *msg) { struct diag_l3_conn *d_l3_conn = (struct diag_l3_conn *)handle; char buffer[200]; - if (diag_l3_debug & DIAG_DEBUG_READ) { - fprintf(stderr,FLFMT "rcv_callback for %d bytes fmt 0x%X conn\n", - FL, msg->len, msg->fmt); + if (diag_l3_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, FLFMT "rcv_callback for %d bytes fmt 0x%X conn\n", FL, + msg->len, msg->fmt); } if (diag_l3_iso14230_decode_response(msg, buffer, sizeof(buffer))) { - fprintf(stderr, "DECODED: %s\n",buffer); + fprintf(stderr, "DECODED: %s\n", buffer); } if (msg->fmt & DIAG_FMT_FRAMED) { @@ -176,18 +172,21 @@ diag_l3_14230_rxcallback(void *handle, struct diag_msg *msg) { d_l3_conn->callback(d_l3_conn->handle, msg); } } else { - fprintf(stderr, FLFMT "problem: got an unframed message!\n" - "Report this !\n", FL); + fprintf(stderr, + FLFMT + "problem: got an unframed message!\n" + "Report this !\n", + FL); } } - -//This just forwards the request to the L2 recv function. I can't see how we could use an -// iso14230 L3 over anything else than an iso14230 L2, so there's no reason to do anything else -// in here. +// This just forwards the request to the L2 recv function. I can't see how we could use an +// iso14230 L3 over anything else than an iso14230 L2, so there's no reason to do anything +// else in here. static int diag_l3_iso14230_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, - void (* rcv_call_back)(void *handle ,struct diag_msg *) , void *handle) { + void (*rcv_call_back)(void *handle, struct diag_msg *), + void *handle) { int rv; @@ -206,29 +205,28 @@ diag_l3_iso14230_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, */ rv = diag_l2_recv(d_l3_conn->d_l3l2_conn, timeout, - diag_l3_14230_rxcallback, (void *)d_l3_conn); + diag_l3_14230_rxcallback, (void *)d_l3_conn); - if (diag_l3_debug & DIAG_DEBUG_READ) { + if (diag_l3_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "_recv returns %d\n", FL, rv); } } else { - //problem : the only time DIAG_L2_FLAG_FRAMED is not set is if - //L2 is raw. Who uses a raw L2 instead of 14230 L2 ??? - //so we'll complain loudly - fprintf(stderr, FLFMT "*** Error : using iso14230 L3 code on a non-iso14230\n", FL); + // problem : the only time DIAG_L2_FLAG_FRAMED is not set is if + // L2 is raw. Who uses a raw L2 instead of 14230 L2 ??? + // so we'll complain loudly + fprintf(stderr, + FLFMT "*** Error : using iso14230 L3 code on a non-iso14230\n", + FL); fprintf(stderr, FLFMT "*** L2 interface !! Please report this.\n", FL); return diag_iseterr(DIAG_ERR_PROTO_NOTSUPP); } - return rv; } - - void -diag_l3_iso14230_decode(UNUSED(struct diag_l3_conn *d_l3_conn), -struct diag_msg *msg, char *buf, size_t bufsize) { +diag_l3_iso14230_decode(UNUSED(struct diag_l3_conn *d_l3_conn), struct diag_msg *msg, + char *buf, size_t bufsize) { if (msg->data[0] & 0x40) { snprintf(buf, bufsize, "ISO14230 response "); } else { @@ -238,7 +236,6 @@ struct diag_msg *msg, char *buf, size_t bufsize) { return; } - /* * Table of english descriptions of the ISO14230 SIDs */ @@ -246,45 +243,46 @@ static const struct { const int id; const char *service; } sids[] = { - {DIAG_KW2K_SI_STADS, "startDiagnosticSession"}, - {DIAG_KW2K_SI_ER, "ecuReset"}, - {DIAG_KW2K_SI_RDFFD, "readFreezeFrameData"}, - {DIAG_KW2K_SI_RDTC, "readDiagnosticTroubleCodes"}, - {DIAG_KW2K_SI_CDI, "clearDiagnosticInformation"}, - {DIAG_KW2K_SI_RDSODTC, "readStatusOfDiagnosticTroubleCodes"}, - {DIAG_KW2K_SI_RDTCBS, "readDiagnosticTroubleCodesByStatus"}, - {DIAG_KW2K_SI_REID, "readEcuId"}, - {DIAG_KW2K_SI_STODS, "stopDiagnosticSession"}, - {DIAG_KW2K_SI_RDDBLI, "readDataByLocalId"}, - {DIAG_KW2K_SI_RDDBCI, "readDataByCommonId"}, - {DIAG_KW2K_SI_RDMBA, "readMemoryByAddress"}, - {DIAG_KW2K_SI_SRDT, "stopRepeatedDataTransmission"}, - {DIAG_KW2K_SI_SDR, "setDataRates"}, - {DIAG_KW2K_SI_SA, "securityAccess"}, - {DIAG_KW2K_SI_DDLI, "dynamicallyDefineLocalId"}, - {DIAG_KW2K_SI_WRDBCI, "writeDataByCommonId"}, - {DIAG_KW2K_SI_IOCBCI, "inputOutputControlByCommonId"}, - {DIAG_KW2K_SI_IOCBLI, "inputOutputControlByLocalId"}, - {DIAG_KW2K_SI_STARBLI, "startRoutineByLocalID"}, - {DIAG_KW2K_SI_STORBLI, "stopRoutineByLocalID"}, - {DIAG_KW2K_SI_RRRBLI, "requestRoutineResultsByLocalId"}, - {DIAG_KW2K_SI_RD, "requestDownload"}, - {DIAG_KW2K_SI_RU, "requestUpload"}, - {DIAG_KW2K_SI_TD, "transfer data"}, - {DIAG_KW2K_SI_RTE, "request transfer exit"}, - {DIAG_KW2K_SI_STARBA, "startRoutineByAddress"}, - {DIAG_KW2K_SI_STORBA, "stopRoutineByAddress"}, - {DIAG_KW2K_SI_RRRBA, "requestRoutineResultsByAddress"}, - {DIAG_KW2K_SI_WRDBLI, "writeDataByLocalId"}, - {DIAG_KW2K_SI_WRMBA, "writeMemoryByAddress"}, - {DIAG_KW2K_SI_TP, "testerPresent"}, - {DIAG_KW2K_SI_ESC, "EscCode"}, - {DIAG_KW2K_SI_SCR, "startCommunication"}, - {DIAG_KW2K_SI_SPR, "stopCommunication"}, - {DIAG_KW2K_SI_ATP, "accessTimingParameters"}, + {DIAG_KW2K_SI_STADS, "startDiagnosticSession"}, + {DIAG_KW2K_SI_ER, "ecuReset"}, + {DIAG_KW2K_SI_RDFFD, "readFreezeFrameData"}, + {DIAG_KW2K_SI_RDTC, "readDiagnosticTroubleCodes"}, + {DIAG_KW2K_SI_CDI, "clearDiagnosticInformation"}, + {DIAG_KW2K_SI_RDSODTC, "readStatusOfDiagnosticTroubleCodes"}, + {DIAG_KW2K_SI_RDTCBS, "readDiagnosticTroubleCodesByStatus"}, + {DIAG_KW2K_SI_REID, "readEcuId"}, + {DIAG_KW2K_SI_STODS, "stopDiagnosticSession"}, + {DIAG_KW2K_SI_RDDBLI, "readDataByLocalId"}, + {DIAG_KW2K_SI_RDDBCI, "readDataByCommonId"}, + {DIAG_KW2K_SI_RDMBA, "readMemoryByAddress"}, + {DIAG_KW2K_SI_SRDT, "stopRepeatedDataTransmission"}, + {DIAG_KW2K_SI_SDR, "setDataRates"}, + {DIAG_KW2K_SI_SA, "securityAccess"}, + {DIAG_KW2K_SI_DDLI, "dynamicallyDefineLocalId"}, + {DIAG_KW2K_SI_WRDBCI, "writeDataByCommonId"}, + {DIAG_KW2K_SI_IOCBCI, "inputOutputControlByCommonId"}, + {DIAG_KW2K_SI_IOCBLI, "inputOutputControlByLocalId"}, + {DIAG_KW2K_SI_STARBLI, "startRoutineByLocalID"}, + {DIAG_KW2K_SI_STORBLI, "stopRoutineByLocalID"}, + {DIAG_KW2K_SI_RRRBLI, "requestRoutineResultsByLocalId"}, + {DIAG_KW2K_SI_RD, "requestDownload"}, + {DIAG_KW2K_SI_RU, "requestUpload"}, + {DIAG_KW2K_SI_TD, "transfer data"}, + {DIAG_KW2K_SI_RTE, "request transfer exit"}, + {DIAG_KW2K_SI_STARBA, "startRoutineByAddress"}, + {DIAG_KW2K_SI_STORBA, "stopRoutineByAddress"}, + {DIAG_KW2K_SI_RRRBA, "requestRoutineResultsByAddress"}, + {DIAG_KW2K_SI_WRDBLI, "writeDataByLocalId"}, + {DIAG_KW2K_SI_WRMBA, "writeMemoryByAddress"}, + {DIAG_KW2K_SI_TP, "testerPresent"}, + {DIAG_KW2K_SI_ESC, "EscCode"}, + {DIAG_KW2K_SI_SCR, "startCommunication"}, + {DIAG_KW2K_SI_SPR, "stopCommunication"}, + {DIAG_KW2K_SI_ATP, "accessTimingParameters"}, }; -static const char *l3_iso14230_sidlookup(const int id) { +static const char * +l3_iso14230_sidlookup(const int id) { unsigned i; for (i = 0; i < ARRAY_SIZE(sids); i++) { if (sids[i].id == id) { @@ -295,7 +293,6 @@ static const char *l3_iso14230_sidlookup(const int id) { return "Unknown SID"; } - /* * Table of english descriptions of the ISO14230 NegResponse codes */ @@ -303,38 +300,39 @@ static const struct { const int id; const char *response; } negresps[] = { - {DIAG_KW2K_RC_GR, "generalReject"}, - {DIAG_KW2K_RC_SNS, "serviceNotSupported"}, - {DIAG_KW2K_RC_SFNS_IF, "subFunctionNotSupported-Invalid Format"}, - {DIAG_KW2K_RC_B_RR, "busy-repeatRequest"}, - {DIAG_KW2K_RC_CNCORSE, "conditionsNoteCorrectOrRequestSequenceError"}, - {DIAG_KW2K_RC_RNC, "routineNotCompleteOrServiceInProgress"}, - {DIAG_KW2K_RC_ROOT, "requestOutOfRange"}, - {DIAG_KW2K_RC_SAD_SAR, "securityAccessDenied-securityAccessRequested"}, - {DIAG_KW2K_RC_IK, "invalidKey"}, - {DIAG_KW2K_RC_ENOA, "exceedNumberOfAttempts"}, - {DIAG_KW2K_RC_RTDNE, "requiredTimeDelayNotExpired"}, - {DIAG_KW2K_RC_DNA, "downloadNotAccepted"}, - {DIAG_KW2K_RC_IDT, "improperDownloadType"}, - {DIAG_KW2K_RC_CNDTSA, "canNotDownloadToSpecifiedAddress"}, - {DIAG_KW2K_RC_CNDNOBR, "canNotDownloadNumberOfBytesRequested"}, - {DIAG_KW2K_RC_UNA, "uploadNotAccepted"}, - {DIAG_KW2K_RC_IUT, "improperUploadType"}, - {DIAG_KW2K_RC_CNUFSA, "canNotUploadFromSpecifiedAddress"}, - {DIAG_KW2K_RC_CNUNOBR, "canNotUploadNumberOfBytesRequested"}, - {DIAG_KW2K_RC_TS, "transferSuspended"}, - {DIAG_KW2K_RC_TA, "transferAborted"}, - {DIAG_KW2K_RC_IAIBT, "illegalAddressInBlockTransfer"}, - {DIAG_KW2K_RC_IBCIBT, "illegalByteCountInBlockTransfer"}, - {DIAG_KW2K_RC_IBTT, "illegalBlockTrasnferType"}, - {DIAG_KW2K_RC_BTCDE, "blockTransferDataChecksumError"}, - {DIAG_KW2K_RC_RCR_RP, "requestCorrectyRcvd-RspPending"}, - {DIAG_KW2K_RC_IBCDBT, "incorrectByteCountDuringBlockTransfer"}, - {DIAG_KW2K_RC_SNSIADS, "serviceNotSupportedInActiveDiagnosticMode//Mfg-Specific"}, - {0, NULL}, + {DIAG_KW2K_RC_GR, "generalReject"}, + {DIAG_KW2K_RC_SNS, "serviceNotSupported"}, + {DIAG_KW2K_RC_SFNS_IF, "subFunctionNotSupported-Invalid Format"}, + {DIAG_KW2K_RC_B_RR, "busy-repeatRequest"}, + {DIAG_KW2K_RC_CNCORSE, "conditionsNoteCorrectOrRequestSequenceError"}, + {DIAG_KW2K_RC_RNC, "routineNotCompleteOrServiceInProgress"}, + {DIAG_KW2K_RC_ROOT, "requestOutOfRange"}, + {DIAG_KW2K_RC_SAD_SAR, "securityAccessDenied-securityAccessRequested"}, + {DIAG_KW2K_RC_IK, "invalidKey"}, + {DIAG_KW2K_RC_ENOA, "exceedNumberOfAttempts"}, + {DIAG_KW2K_RC_RTDNE, "requiredTimeDelayNotExpired"}, + {DIAG_KW2K_RC_DNA, "downloadNotAccepted"}, + {DIAG_KW2K_RC_IDT, "improperDownloadType"}, + {DIAG_KW2K_RC_CNDTSA, "canNotDownloadToSpecifiedAddress"}, + {DIAG_KW2K_RC_CNDNOBR, "canNotDownloadNumberOfBytesRequested"}, + {DIAG_KW2K_RC_UNA, "uploadNotAccepted"}, + {DIAG_KW2K_RC_IUT, "improperUploadType"}, + {DIAG_KW2K_RC_CNUFSA, "canNotUploadFromSpecifiedAddress"}, + {DIAG_KW2K_RC_CNUNOBR, "canNotUploadNumberOfBytesRequested"}, + {DIAG_KW2K_RC_TS, "transferSuspended"}, + {DIAG_KW2K_RC_TA, "transferAborted"}, + {DIAG_KW2K_RC_IAIBT, "illegalAddressInBlockTransfer"}, + {DIAG_KW2K_RC_IBCIBT, "illegalByteCountInBlockTransfer"}, + {DIAG_KW2K_RC_IBTT, "illegalBlockTrasnferType"}, + {DIAG_KW2K_RC_BTCDE, "blockTransferDataChecksumError"}, + {DIAG_KW2K_RC_RCR_RP, "requestCorrectyRcvd-RspPending"}, + {DIAG_KW2K_RC_IBCDBT, "incorrectByteCountDuringBlockTransfer"}, + {DIAG_KW2K_RC_SNSIADS, "serviceNotSupportedInActiveDiagnosticMode//Mfg-Specific"}, + {0, NULL}, }; -static const char *l3_iso14230_neglookup(const int id) { +static const char * +l3_iso14230_neglookup(const int id) { unsigned i; for (i = 0; i < ARRAY_SIZE(negresps); i++) { if (negresps[i].id == id) { @@ -345,15 +343,14 @@ static const char *l3_iso14230_neglookup(const int id) { return "Unknown Response code"; } - const struct diag_l3_proto diag_l3_iso14230 = { "ISO14230", diag_l3_base_start, diag_l3_base_stop, diag_l3_iso14230_send, diag_l3_iso14230_recv, - NULL, //ioctl + NULL, // ioctl diag_l3_base_request, diag_l3_iso14230_decode, - NULL //timer + NULL // timer }; diff --git a/scantool/diag_l3_iso14230.h b/scantool/diag_l3_iso14230.h index fa6fc72b..deeb5e53 100644 --- a/scantool/diag_l3_iso14230.h +++ b/scantool/diag_l3_iso14230.h @@ -29,12 +29,12 @@ extern "C" { // XXX L2 uses a nifty "2/3 * P3max" formula in to calculate keepalive interval. // I'm not sure why we need this as well. -#define ISO14230_KEEPALIVE 3500 //ms timeout before keepalive signal on OBD bus. -//That keepalive corresponds to the P3 timing value; certain ECUs allow +#define ISO14230_KEEPALIVE 3500 // ms timeout before keepalive signal on OBD bus. +// That keepalive corresponds to the P3 timing value; certain ECUs allow // changes (SID 83, AccessTimingParameter) to modify P3. But by default they // should be configured to accept 55 ms < P3 < 5000 ms #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L3_ISO14230_H_ */ diff --git a/scantool/diag_l3_saej1979.c b/scantool/diag_l3_saej1979.c index 418d2d63..33160576 100644 --- a/scantool/diag_l3_saej1979.c +++ b/scantool/diag_l3_saej1979.c @@ -36,14 +36,13 @@ #include "diag_l3_saej1979.h" #include "utlist.h" - /* internal data used by each connection */ struct l3_j1979_int { - uint8_t src; //source address ("tester ID") + uint8_t src; // source address ("tester ID") /* Received data buffer, and offset into it */ uint8_t rxbuf[MAXRBUF]; - int rxoffset; + int rxoffset; }; /* @@ -57,8 +56,9 @@ struct l3_j1979_int { * Get this wrong and all will fail, it's used to frame the incoming messages * properly */ -static int diag_l3_j1979_getlen(uint8_t *data, int len) { - static const int rqst_lengths[] = { -1, 2, 3, 1, 1, 2, 2, 1, 7, 2 }; +static int +diag_l3_j1979_getlen(uint8_t *data, int len) { + static const int rqst_lengths[] = {-1, 2, 3, 1, 1, 2, 2, 1, 7, 2}; int rv; uint8_t mode; @@ -68,7 +68,8 @@ static int diag_l3_j1979_getlen(uint8_t *data, int len) { mode = data[0]; - //J1979 specifies 9 modes (0x01 - 0x09) except with iso15765 (CAN) which has 0x0A modes. + // J1979 specifies 9 modes (0x01 - 0x09) except with iso15765 (CAN) which has 0x0A + // modes. if (mode > 0x49) { return diag_iseterr(DIAG_ERR_BADDATA); @@ -83,28 +84,28 @@ static int diag_l3_j1979_getlen(uint8_t *data, int len) { rv = DIAG_ERR_BADDATA; - //Here, all modes < 0x0A are taken care of. - //Modes > 0x40 are responses and therefore need specific treatment - //data[1] contains the PID / TID number. + // Here, all modes < 0x0A are taken care of. + // Modes > 0x40 are responses and therefore need specific treatment + // data[1] contains the PID / TID number. switch (mode) { case 0x41: - case 0x42: //almost identical modes except PIDS 1,2 + case 0x42: // almost identical modes except PIDS 1,2 // Note : mode 2 responses will be +1 longer because of the frame_no byte. if ((data[1] & 0x1f) == 0) { /* return supported PIDs */ - rv=6; //6.1.2.2 + rv = 6; // 6.1.2.2 break; } switch (data[1]) { - case 1: //Status. Only with service 01 (mode 0x41) + case 1: // Status. Only with service 01 (mode 0x41) if (mode == 0x42) { - rv=DIAG_ERR_BADDATA; + rv = DIAG_ERR_BADDATA; } else { rv = 6; } break; - case 2: //request freeze DTC. Only with Service 02 (mode=0x42) + case 2: // request freeze DTC. Only with Service 02 (mode=0x42) if (mode == 0x41) { rv = DIAG_ERR_BADDATA; } else { @@ -116,7 +117,7 @@ static int diag_l3_j1979_getlen(uint8_t *data, int len) { break; case 0x04: case 0x05: - rv=3; + rv = 3; break; case 0x06: case 0x07: @@ -126,31 +127,32 @@ static int diag_l3_j1979_getlen(uint8_t *data, int len) { case 0x56: case 0x57: case 0x58: - //XXX For PIDs 0x06 thru 0x09 and 0x55-0x58, there may be an additional data byte based on PID 0x13 / 0x1D results + // XXX For PIDs 0x06 thru 0x09 and 0x55-0x58, there may be an + // additional data byte based on PID 0x13 / 0x1D results // (presence of a bank3 O2 sensor. Not implemented... - rv=3; + rv = 3; break; case 0x0A: - case 0x0B: //IMAP - rv=3; + case 0x0B: // IMAP + rv = 3; break; - case 0x0C: //RPM - rv=4; + case 0x0C: // RPM + rv = 4; break; - case 0x0D: //VSS + case 0x0D: // VSS case 0x0E: - case 0x0F: //IAT - rv=3; + case 0x0F: // IAT + rv = 3; break; - case 0x10: //MAF - rv=4; + case 0x10: // MAF + rv = 4; break; - case 0x11: //TPS + case 0x11: // TPS case 0x12: - case 0x13: //O2Sloc + case 0x13: // O2Sloc rv = 3; break; - case 0x14: //0x14-0x1B:O2 stuff + case 0x14: // 0x14-0x1B:O2 stuff case 0x15: case 0x16: case 0x17: @@ -160,56 +162,58 @@ static int diag_l3_j1979_getlen(uint8_t *data, int len) { case 0x1B: rv = 4; break; - case 0x1C: //OBD - case 0x1D: //O2Sloc + case 0x1C: // OBD + case 0x1D: // O2Sloc case 0x1E: rv = 2; break; - case 0x1F: //RUNTM + case 0x1F: // RUNTM rv = 4; break; - //TODO : PIDS 0x21 etc + // TODO : PIDS 0x21 etc default: /* Sometime add J2190 support (PID>0x1F) */ rv = DIAG_ERR_BADDATA; break; - } //PIDs for modes 1 and 2 - //For mode 2 responses, actual length is 1 byte longer than Mode 1 resps because of Frame No + } // PIDs for modes 1 and 2 + // For mode 2 responses, actual length is 1 byte longer than Mode 1 resps + // because of Frame No if (mode == 0x42 && rv) { rv += 1; } break; case 0x43: - rv=7; //6.3.2.4 + rv = 7; // 6.3.2.4 break; case 0x44: - rv = 1; //6.4.2.2 + rv = 1; // 6.4.2.2 break; case 0x45: if ((data[1] & 0x1f) == 0) { - rv = 7; // Read supported TIDs, 6.5.2.2 + rv = 7; // Read supported TIDs, 6.5.2.2 } else if (data[1] <= 4) { - rv=4; //J1979 sec 6.5.2.4 : conditional TIDs. + rv = 4; // J1979 sec 6.5.2.4 : conditional TIDs. } else { rv = 6; // Request TID result } break; case 0x46: - //6.6.2.2 supported PIDs : len=7 - //6.6.2.4 : 7 bytes; last 2 are "conditional" in meaning only, always present ?? - case 0x47: //6.7.2.2 - case 0x48: //6.8.2.1 + // 6.6.2.2 supported PIDs : len=7 + // 6.6.2.4 : 7 bytes; last 2 are "conditional" in meaning only, always + // present ?? + case 0x47: // 6.7.2.2 + case 0x48: // 6.8.2.1 rv = 7; break; - case 0x49: //6.9.1 - if ((data[1] & 0x1f) ==0) { - rv=7; //supported INFOTYPES + case 0x49: // 6.9.1 + if ((data[1] & 0x1f) == 0) { + rv = 7; // supported INFOTYPES } else if (data[1] & 1) { - //INFOTYPE is odd: - rv=7; + // INFOTYPE is odd: + rv = 7; } else { - //even - rv=3; + // even + rv = 3; } break; default: @@ -218,7 +222,6 @@ static int diag_l3_j1979_getlen(uint8_t *data, int len) { return rv; } - /* * Send a J1979 packet - we know the length (from looking at the data) * since we're L3, we assume msg->data[0] is the mode (service id), i.e. there @@ -229,17 +232,17 @@ diag_l3_j1979_send(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg) { int rv; struct diag_l2_conn *d_conn; struct l3_j1979_int *l3i = d_l3_conn->l3_int; -// uint8_t buf[32]; + // uint8_t buf[32]; /* Get l2 connection info */ d_conn = d_l3_conn->d_l3l2_conn; - if (diag_l3_debug & DIAG_DEBUG_WRITE) { - fprintf(stderr, FLFMT "send %d bytes, l2 flags 0x%X\n", FL, - msg->len, d_l3_conn->d_l3l2_flags); + if (diag_l3_debug_load() & DIAG_DEBUG_WRITE) { + fprintf(stderr, FLFMT "send %d bytes, l2 flags 0x%X\n", FL, msg->len, + d_l3_conn->d_l3l2_flags); } - //and make sure src address was set in msg: + // and make sure src address was set in msg: if (!msg->src) { msg->src = 0xF1; } @@ -249,11 +252,10 @@ diag_l3_j1979_send(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg) { l3i->src = msg->src; } - //we can't set destination address because it's L2-defined. + // we can't set destination address because it's L2-defined. // (iso14230 : dest = 0x33 phys; // (iso9141 + J1850 : dest = 0x6A ) - /* L2 does framing, adds addressing and CRC, so do nothing else*/ rv = diag_l2_send(d_conn, msg); @@ -273,11 +275,10 @@ diag_l3_rcv_callback(void *handle, struct diag_msg *msg) { struct diag_l3_conn *d_l3_conn = (struct diag_l3_conn *)handle; struct l3_j1979_int *l3i = d_l3_conn->l3_int; - if (diag_l3_debug & DIAG_DEBUG_READ) { + if (diag_l3_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, - FLFMT - "rcv_callback for %d bytes fmt 0x%X conn rxoffset %d\n", - FL, msg->len, msg->fmt, l3i->rxoffset); + FLFMT "rcv_callback for %d bytes fmt 0x%X conn rxoffset %d\n", FL, + msg->len, msg->fmt, l3i->rxoffset); } if (msg->fmt & DIAG_FMT_FRAMED) { @@ -287,13 +288,13 @@ diag_l3_rcv_callback(void *handle, struct diag_msg *msg) { } } else { /* Add data to the receive buffer on the L3 connection */ - memcpy(&l3i->rxbuf[l3i->rxoffset], - msg->data, msg->len); //XXX possible buffer overflow ! + memcpy(&l3i->rxbuf[l3i->rxoffset], msg->data, msg->len); // XXX possible + // buffer overflow + // ! l3i->rxoffset += msg->len; } } - /* * Process_data() - this is the routine that works out the framing * of the data , if recv() was always called at the correct time and @@ -304,12 +305,13 @@ diag_l3_rcv_callback(void *handle, struct diag_msg *msg) { * Look at the data and try and work out the length of the message based * on the J1979 protocol. Returns length (excluding headers & checksum !) * VVVVVVVV - * Note: J1979 doesn't specify particular checksums beyond what 9141 and 14230 already provide, - * i.e. a J1979 message is maximum 7 bytes long except on CANBUS. - * headers, address and checksum are handled and stripped at the l2 level (9141, 14230, etc); + * Note: J1979 doesn't specify particular checksums beyond what 9141 and 14230 already + * provide, i.e. a J1979 message is maximum 7 bytes long except on CANBUS. headers, address + * and checksum are handled and stripped at the l2 level (9141, 14230, etc); * - * Another validity check is comparing message length (expected vs real); not implemented XXX? - * Upper levels can also verify that the responses correspond to the requests (i.e. Service ID 0x02 -> 0x42 ) + * Another validity check is comparing message length (expected vs real); not implemented + * XXX? Upper levels can also verify that the responses correspond to the requests (i.e. + * Service ID 0x02 -> 0x42 ) * XXX Broken for the moment because I'm moving the header stuff completely out of L3 * */ @@ -321,30 +323,33 @@ diag_l3_j1979_process_data(struct diag_l3_conn *d_l3_conn) { struct l3_j1979_int *l3i = d_l3_conn->l3_int; while (l3i->rxoffset) { - int badpacket=0; + int badpacket = 0; sae_msglen = diag_l3_j1979_getlen(l3i->rxbuf, - l3i->rxoffset); //set expected packet length based on SID + TID + l3i->rxoffset); // set expected packet + // length based on SID + + // TID - if (diag_l3_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr,FLFMT "process_data rxoffset is %d sae_msglen is %ld\n", + if (diag_l3_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, + FLFMT "process_data rxoffset is %d sae_msglen is %ld\n", FL, l3i->rxoffset, (long)sae_msglen); - fprintf(stderr,FLFMT "process_data hex data is ", - FL); - diag_data_dump(stderr, l3i->rxbuf, l3i->rxoffset -1); - fprintf(stderr,"\n"); + fprintf(stderr, FLFMT "process_data hex data is ", FL); + diag_data_dump(stderr, l3i->rxbuf, l3i->rxoffset - 1); + fprintf(stderr, "\n"); } if (sae_msglen < 0 || sae_msglen > 255) { if (sae_msglen == DIAG_ERR_INCDATA) { - /* Not enough data in this frame, this isn't catastrophic */ + /* Not enough data in this frame, this isn't catastrophic + */ return; } /* Duff data received, bad news ! */ badpacket = 1; } - if (badpacket || (sae_msglen <= l3i->rxoffset )) { + if (badpacket || (sae_msglen <= l3i->rxoffset)) { /* Bad packet, or full packet, need to tell user */ uint8_t *data = NULL; @@ -368,20 +373,19 @@ diag_l3_j1979_process_data(struct diag_l3_conn *d_l3_conn) { } else { msg->fmt = DIAG_FMT_ISO_FUNCADDR; // XXX This won't do at all ! - //msg->type = l3i->rxbuf[0]; //nobody checks this + // msg->type = l3i->rxbuf[0]; //nobody checks this msg->dest = l3i->rxbuf[1]; msg->src = l3i->rxbuf[2]; /* Copy in J1979 part of message */ memcpy(data, &l3i->rxbuf[3], (size_t)(sae_msglen - 4)); /* remove whole message from rx buf */ - memmove(l3i->rxbuf, - &l3i->rxbuf[sae_msglen], + memmove(l3i->rxbuf, &l3i->rxbuf[sae_msglen], (size_t)sae_msglen); l3i->rxoffset -= sae_msglen; msg->data = data; - msg->len = (uint8_t) sae_msglen - 4; + msg->len = (uint8_t)sae_msglen - 4; } msg->rxtime = diag_os_getms(); @@ -389,7 +393,8 @@ diag_l3_j1979_process_data(struct diag_l3_conn *d_l3_conn) { /* Add it to the list */ LL_CONCAT(d_l3_conn->msg, msg); free(data); - free(msg); //we don't use diag_freemsg() since we alloc'ed it manually + free(msg); // we don't use diag_freemsg() since we alloc'ed it + // manually if (badpacket) { /* No point in continuing */ break; @@ -411,13 +416,13 @@ diag_l3_j1979_process_data(struct diag_l3_conn *d_l3_conn) { */ static int diag_l3_j1979_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, - void (* rcv_call_back)(void *handle ,struct diag_msg *) , void *handle) { + void (*rcv_call_back)(void *handle, struct diag_msg *), void *handle) { int rv; struct diag_msg *msg; unsigned int tout; int state; -//State machine: -#define ST_STATE1 1 // timeout=0 to get data already in buffer +// State machine: +#define ST_STATE1 1 // timeout=0 to get data already in buffer #define ST_STATE2 2 #define ST_STATE3 3 #define ST_STATE4 4 @@ -446,25 +451,24 @@ diag_l3_j1979_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, while (1) { /* State machine for setting timeout values */ switch (state) { - case ST_STATE1: - tout = 0; - break; - case ST_STATE2: - tout = timeout; - break; - case ST_STATE3: - tout = 5; /* XXX should be p4max */ - break; - case ST_STATE4: - tout = timeout; - break; - default: - break; + case ST_STATE1: + tout = 0; + break; + case ST_STATE2: + tout = timeout; + break; + case ST_STATE3: + tout = 5; /* XXX should be p4max */ + break; + case ST_STATE4: + tout = timeout; + break; + default: + break; } - if (diag_l3_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "recv state %d tout %u\n", FL, - state, tout); + if (diag_l3_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "recv state %d tout %u\n", FL, state, tout); } /* @@ -472,10 +476,10 @@ diag_l3_j1979_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, * call the callback routine if needed, we use a timeout * of zero to see if data exists *now*, */ - rv = diag_l2_recv(d_l3_conn->d_l3l2_conn, tout, - diag_l3_rcv_callback, (void *)d_l3_conn); + rv = diag_l2_recv(d_l3_conn->d_l3l2_conn, tout, diag_l3_rcv_callback, + (void *)d_l3_conn); - if (diag_l3_debug & DIAG_DEBUG_PROTO) { + if (diag_l3_debug_load() & DIAG_DEBUG_PROTO) { fprintf(stderr, FLFMT "recv returns %d\n", FL, rv); } @@ -484,11 +488,11 @@ diag_l3_j1979_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, } if (rv == DIAG_ERR_TIMEOUT) { - if ( (state == ST_STATE3) || (state == ST_STATE4) ) { + if ((state == ST_STATE3) || (state == ST_STATE4)) { /* Finished */ break; } - if ( (state == ST_STATE1) && (d_l3_conn->msg == NULL) ) { + if ((state == ST_STATE1) && (d_l3_conn->msg == NULL)) { /* * Try again, with real timeout * (and thus sleep) @@ -503,10 +507,8 @@ diag_l3_j1979_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, /* Process the data into messages */ diag_l3_j1979_process_data(d_l3_conn); - if (diag_l3_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, - FLFMT - "recv process_data called, msg %p\n", + if (diag_l3_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "recv process_data called, msg %p\n", FL, (void *)d_l3_conn->msg); } @@ -543,8 +545,6 @@ diag_l3_j1979_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, return rv; } - - /* * This is called without the ADDR_ADDR_1 on it, ie it contains * just the SAEJ1979 data @@ -553,13 +553,13 @@ diag_l3_j1979_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout, */ void -diag_l3_j1979_decode(UNUSED(struct diag_l3_conn *d_l3_conn), -struct diag_msg *msg, char *buf, size_t bufsize) { +diag_l3_j1979_decode(UNUSED(struct diag_l3_conn *d_l3_conn), struct diag_msg *msg, + char *buf, size_t bufsize) { unsigned i, j; char buf2[80]; - char area; //for DTCs + char area; // for DTCs if (msg->data[0] & 0x40) { snprintf(buf, bufsize, "J1979 response "); @@ -568,150 +568,157 @@ struct diag_msg *msg, char *buf, size_t bufsize) { } switch (msg->data[0]) { - case 0x01: - snprintf(buf2, sizeof(buf2), "Mode 1 PID 0x%02X", msg->data[1]); - smartcat(buf, bufsize, buf2); - break; - case 0x41: - snprintf(buf2, sizeof(buf2),"Mode 1 Data: PID 0x%02X ", msg->data[1]); - smartcat(buf, bufsize, buf2); - for (i=2; i < msg->len; i++) { - snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); - smartcat(buf, bufsize, buf2); - } - break; - case 0x02: - snprintf(buf2, sizeof(buf2), "Mode 2 PID 0x%02X Frame 0x%02X", msg->data[1], - msg->data[2]); + case 0x01: + snprintf(buf2, sizeof(buf2), "Mode 1 PID 0x%02X", msg->data[1]); + smartcat(buf, bufsize, buf2); + break; + case 0x41: + snprintf(buf2, sizeof(buf2), "Mode 1 Data: PID 0x%02X ", msg->data[1]); + smartcat(buf, bufsize, buf2); + for (i = 2; i < msg->len; i++) { + snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); smartcat(buf, bufsize, buf2); - break; - case 0x42: - snprintf(buf2, sizeof(buf2),"Mode 2 FreezeFrame Data: PID 0x%02X Frame 0x%02X ", - msg->data[1], msg->data[2]); + } + break; + case 0x02: + snprintf(buf2, sizeof(buf2), "Mode 2 PID 0x%02X Frame 0x%02X", + msg->data[1], msg->data[2]); + smartcat(buf, bufsize, buf2); + break; + case 0x42: + snprintf(buf2, sizeof(buf2), + "Mode 2 FreezeFrame Data: PID 0x%02X Frame 0x%02X ", msg->data[1], + msg->data[2]); + smartcat(buf, bufsize, buf2); + for (i = 3; i < msg->len; i++) { + snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); smartcat(buf, bufsize, buf2); - for (i=3; i < msg->len; i++) { - snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); - smartcat(buf, bufsize, buf2); + } + break; + case 0x03: + snprintf(buf2, sizeof(buf2), "Mode 3 (Powertrain DTCs)"); + smartcat(buf, bufsize, buf2); + break; + case 0x07: + snprintf(buf2, sizeof(buf2), + "Request Non-Continuous Monitor System Test Results"); + smartcat(buf, bufsize, buf2); + break; + case 0x47: + snprintf(buf2, sizeof(buf2), "Non-Continuous Monitor System "); + smartcat(buf, bufsize, buf2); + /* Fallthru */ + case 0x43: + snprintf(buf2, sizeof(buf2), "DTCs: "); + smartcat(buf, bufsize, buf2); + for (i = 0, j = 1; i < 3; i++, j += 2) { + if ((msg->data[j] == 0) && (msg->data[j + 1] == 0)) { + continue; } - break; - case 0x03: - snprintf(buf2, sizeof(buf2),"Mode 3 (Powertrain DTCs)"); - smartcat(buf, bufsize, buf2); - break; - case 0x07: - snprintf(buf2, sizeof(buf2), - "Request Non-Continuous Monitor System Test Results"); - smartcat(buf, bufsize, buf2); - break; - case 0x47: - snprintf(buf2, sizeof(buf2), "Non-Continuous Monitor System "); - smartcat(buf, bufsize, buf2); - /* Fallthru */ - case 0x43: - snprintf(buf2, sizeof(buf2),"DTCs: "); - smartcat(buf, bufsize, buf2); - for (i=0, j=1; i<3; i++, j+=2) { - if ((msg->data[j] == 0) && - (msg->data[j + 1] == 0)) { - continue; - } - switch ((msg->data[j] >> 6) & 0x03) { - case 0: - area = 'P'; - break; - case 1: - area = 'C'; - break; - case 2: - area = 'B'; - break; - case 3: - area = 'U'; - break; - default: - fprintf(stderr, "Illegal msg->data[%d] value\n", j); - area = 'X'; - break; - } - snprintf(buf2, sizeof(buf2), "%c%02X%02X ", area, msg->data[j] & 0x3f, - msg->data[j+1]&0xff); - smartcat(buf, bufsize, buf2); - } - break; - case 0x04: - snprintf(buf2, sizeof(buf2), "Clear DTCs"); - smartcat(buf, bufsize, buf2); - break; - case 0x44: - snprintf(buf2, sizeof(buf2), "DTCs cleared"); - smartcat(buf, bufsize, buf2); - break; - case 0x05: - snprintf(buf2, sizeof(buf2), "Oxygen Sensor Test ID 0x%02X Sensor 0x%02X", - msg->data[1], msg->data[2]); - smartcat(buf, bufsize, buf2); - break; - case 0x45: - snprintf(buf2, sizeof(buf2), "Oxygen Sensor TID 0x%02X Sensor 0x%02X ", - msg->data[1], msg->data[2]); - smartcat(buf, bufsize, buf); - for (i=3; i < msg->len; i++) { - snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); - smartcat(buf, bufsize, buf2); + switch ((msg->data[j] >> 6) & 0x03) { + case 0: + area = 'P'; + break; + case 1: + area = 'C'; + break; + case 2: + area = 'B'; + break; + case 3: + area = 'U'; + break; + default: + fprintf(stderr, "Illegal msg->data[%d] value\n", j); + area = 'X'; + break; } - break; - case 0x06: - snprintf(buf2, sizeof(buf2), "Onboard monitoring test request TID 0x%02X", msg->data[1]); + snprintf(buf2, sizeof(buf2), "%c%02X%02X ", area, + msg->data[j] & 0x3f, msg->data[j + 1] & 0xff); smartcat(buf, bufsize, buf2); - break; - case 0x46: - snprintf(buf2, sizeof(buf2),"Onboard monitoring test result TID 0x%02X ", msg->data[1]); - smartcat(buf, bufsize, buf2); - for (i=2; i < msg->len; i++) { - snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); - smartcat(buf, bufsize, buf2); - } - break; - case 0x08: - snprintf(buf2, sizeof(buf2), "Request control of onboard system TID 0x%02X", msg->data[1]); + } + break; + case 0x04: + snprintf(buf2, sizeof(buf2), "Clear DTCs"); + smartcat(buf, bufsize, buf2); + break; + case 0x44: + snprintf(buf2, sizeof(buf2), "DTCs cleared"); + smartcat(buf, bufsize, buf2); + break; + case 0x05: + snprintf(buf2, sizeof(buf2), "Oxygen Sensor Test ID 0x%02X Sensor 0x%02X", + msg->data[1], msg->data[2]); + smartcat(buf, bufsize, buf2); + break; + case 0x45: + snprintf(buf2, sizeof(buf2), "Oxygen Sensor TID 0x%02X Sensor 0x%02X ", + msg->data[1], msg->data[2]); + smartcat(buf, bufsize, buf); + for (i = 3; i < msg->len; i++) { + snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); smartcat(buf, bufsize, buf2); - break; - case 0x48: - snprintf(buf2, sizeof(buf2), "Control of onboard system response TID 0x%02X ", msg->data[1]); + } + break; + case 0x06: + snprintf(buf2, sizeof(buf2), "Onboard monitoring test request TID 0x%02X", + msg->data[1]); + smartcat(buf, bufsize, buf2); + break; + case 0x46: + snprintf(buf2, sizeof(buf2), "Onboard monitoring test result TID 0x%02X ", + msg->data[1]); + smartcat(buf, bufsize, buf2); + for (i = 2; i < msg->len; i++) { + snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); smartcat(buf, bufsize, buf2); - for (i=2; i < msg->len; i++) { - snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); - smartcat(buf, bufsize, buf2); - } - break; - case 0x09: - snprintf(buf2, sizeof(buf2), "Request vehicle information infotype 0x%02X", msg->data[1]); + } + break; + case 0x08: + snprintf(buf2, sizeof(buf2), + "Request control of onboard system TID 0x%02X", msg->data[1]); + smartcat(buf, bufsize, buf2); + break; + case 0x48: + snprintf(buf2, sizeof(buf2), + "Control of onboard system response TID 0x%02X ", msg->data[1]); + smartcat(buf, bufsize, buf2); + for (i = 2; i < msg->len; i++) { + snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); smartcat(buf, bufsize, buf2); - break; - case 0x49: - snprintf(buf2, sizeof(buf2), "Vehicle information infotype 0x%02X ", msg->data[1]); + } + break; + case 0x09: + snprintf(buf2, sizeof(buf2), "Request vehicle information infotype 0x%02X", + msg->data[1]); + smartcat(buf, bufsize, buf2); + break; + case 0x49: + snprintf(buf2, sizeof(buf2), "Vehicle information infotype 0x%02X ", + msg->data[1]); + smartcat(buf, bufsize, buf2); + for (i = 2; i < msg->len; i++) { + snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); smartcat(buf, bufsize, buf2); - for (i=2; i < msg->len; i++) { - snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); - smartcat(buf, bufsize, buf2); - } - break; - default: - snprintf(buf2, sizeof(buf2),"UnknownType 0x%02X: Data Dump: ", msg->data[0]); + } + break; + default: + snprintf(buf2, sizeof(buf2), + "UnknownType 0x%02X: Data Dump: ", msg->data[0]); + smartcat(buf, bufsize, buf2); + for (i = 0; i < msg->len; i++) { + snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); smartcat(buf, bufsize, buf2); - for (i=0; i < msg->len; i++) { - snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]); - smartcat(buf, bufsize, buf2); - } + } } return; } - -//Send a service 1, pid 0 request and check for a valid reply. -//ret 0 if ok -static int diag_l3_j1979_keepalive(struct diag_l3_conn *d_l3_conn) { +// Send a service 1, pid 0 request and check for a valid reply. +// ret 0 if ok +static int +diag_l3_j1979_keepalive(struct diag_l3_conn *d_l3_conn) { struct diag_msg msg = {0}; struct diag_msg *rxmsg; uint8_t data[6]; @@ -725,8 +732,8 @@ static int diag_l3_j1979_keepalive(struct diag_l3_conn *d_l3_conn) { msg.data = data; msg.len = 2; - data[0] = 1 ; /* Mode 1 */ - data[1] = 0; /* Pid 0 */ + data[0] = 1; /* Mode 1 */ + data[1] = 0; /* Pid 0 */ /* * And set the source address, if no sends have happened, then @@ -739,15 +746,15 @@ static int diag_l3_j1979_keepalive(struct diag_l3_conn *d_l3_conn) { } /* Send it: using l3_request() makes sure the connection's timestamp is updated */ - rxmsg=diag_l3_request(d_l3_conn, &msg, &errval); + rxmsg = diag_l3_request(d_l3_conn, &msg, &errval); if (rxmsg == NULL) { return diag_iseterr(DIAG_ERR_TIMEOUT); } - if (diag_l3_debug & DIAG_DEBUG_PROTO) { - fprintf(stderr, FLFMT "keepalive : got %u bytes, %02X ...\n", - FL, rxmsg->len, rxmsg->data[0]); + if (diag_l3_debug_load() & DIAG_DEBUG_PROTO) { + fprintf(stderr, FLFMT "keepalive : got %u bytes, %02X ...\n", FL, + rxmsg->len, rxmsg->data[0]); } /* Check if its a valid SID 1 PID 0 response */ @@ -758,15 +765,18 @@ static int diag_l3_j1979_keepalive(struct diag_l3_conn *d_l3_conn) { diag_freemsg(rxmsg); return 0; - } //_start : send service 1 pid 0 request (J1979 keepalive); according to SAE J1979 (p.7) : -// " IMPORTANT — All emissions-related OBD ECUs which at least support one of the services defined in this -// document shall support service $01 and PID $00. Service $01 with PID $00 is defined as the universal -// “initialisation/keep alive/ping” message for all emissions-related OBD ECUs. " -//That sounds like a sure-fire way to make sure we have a succesful connection to a J1979-compliant ECU. -int diag_l3_j1979_start(struct diag_l3_conn *d_l3_conn) { +// " IMPORTANT ? All emissions-related OBD ECUs which at least support one of the services +// defined in this +// document shall support service $01 and PID $00. Service $01 with PID $00 is defined +// as the universal ?initialisation/keep alive/ping? message for all emissions-related +// OBD ECUs. " That sounds like a sure-fire way to make sure we have a succesful connection +// to a +// J1979-compliant ECU. +int +diag_l3_j1979_start(struct diag_l3_conn *d_l3_conn) { int rv; struct l3_j1979_int *l3i; @@ -779,20 +789,25 @@ int diag_l3_j1979_start(struct diag_l3_conn *d_l3_conn) { d_l3_conn->l3_int = l3i; - rv=diag_l3_j1979_keepalive(d_l3_conn); + rv = diag_l3_j1979_keepalive(d_l3_conn); - if (rv<0) { - fprintf(stderr, FLFMT "J1979 Keepalive failed ! Try to disconnect and reconnect.\n", FL); + if (rv < 0) { + fprintf(stderr, + FLFMT + "J1979 Keepalive failed ! Try to disconnect and " + "reconnect.\n", + FL); free(l3i); return diag_iseterr(rv); } - return 0; } -/* Stop communications : nothing defined, other than letting the link timeout (L2 defined). */ -int dl3_j1979_stop(struct diag_l3_conn *d_l3_conn) { +/* Stop communications : nothing defined, other than letting the link timeout (L2 defined). + */ +int +dl3_j1979_stop(struct diag_l3_conn *d_l3_conn) { assert(d_l3_conn != NULL); free(d_l3_conn->l3_int); return 0; @@ -806,8 +821,6 @@ int dl3_j1979_stop(struct diag_l3_conn *d_l3_conn) { static int diag_l3_j1979_timer(struct diag_l3_conn *d_l3_conn, unsigned long ms) { int rv; - int debug_l2_orig=diag_l2_debug; //save debug flags; disable them for this procedure - int debug_l1_orig=diag_l1_debug; /* J1979 needs keepalive at least every 5 seconds (P3), we use 3.5s */ @@ -823,34 +836,31 @@ diag_l3_j1979_timer(struct diag_l3_conn *d_l3_conn, unsigned long ms) { /* OK, do keep alive on this connection */ - if (diag_l3_debug & DIAG_DEBUG_TIMER) { + if (diag_l3_debug_load() & DIAG_DEBUG_TIMER) { /* XXX Not async-signal-safe */ - fprintf(stderr, FLFMT "\nP3 timeout impending for %p %lu ms\n", - FL, (void *)d_l3_conn, ms); + fprintf(stderr, FLFMT "\nP3 timeout impending for %p %lu ms\n", FL, + (void *)d_l3_conn, ms); } - diag_l2_debug=0; //disable - diag_l1_debug=0; - rv=diag_l3_j1979_keepalive(d_l3_conn); + rv = diag_l3_j1979_keepalive(d_l3_conn); - if (rv<0) { - fprintf(stderr, FLFMT "J1979 Keepalive failed ! Try to disconnect and reconnect.\n", FL); + if (rv < 0) { + fprintf(stderr, + FLFMT + "J1979 Keepalive failed ! Try to disconnect and " + "reconnect.\n", + FL); } - diag_l2_debug=debug_l2_orig; //restore debug flags - diag_l1_debug=debug_l1_orig; - return rv; } -const struct diag_l3_proto diag_l3_j1979 = { - "SAEJ1979", - diag_l3_j1979_start, - dl3_j1979_stop, - diag_l3_j1979_send, - diag_l3_j1979_recv, - NULL, //ioctl - diag_l3_base_request, - diag_l3_j1979_decode, - diag_l3_j1979_timer -}; +const struct diag_l3_proto diag_l3_j1979 = {"SAEJ1979", + diag_l3_j1979_start, + dl3_j1979_stop, + diag_l3_j1979_send, + diag_l3_j1979_recv, + NULL, // ioctl + diag_l3_base_request, + diag_l3_j1979_decode, + diag_l3_j1979_timer}; diff --git a/scantool/diag_l3_saej1979.h b/scantool/diag_l3_saej1979.h index 9d211a88..efe4a5b6 100644 --- a/scantool/diag_l3_saej1979.h +++ b/scantool/diag_l3_saej1979.h @@ -27,9 +27,9 @@ extern "C" { #endif -#define J1979_KEEPALIVE 3500 //ms timeout between keepalive messages on OBD bus +#define J1979_KEEPALIVE 3500 // ms timeout between keepalive messages on OBD bus #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L3_J1979_H_ */ diff --git a/scantool/diag_l3_vag.c b/scantool/diag_l3_vag.c index e8e02b75..e18a2d12 100644 --- a/scantool/diag_l3_vag.c +++ b/scantool/diag_l3_vag.c @@ -57,9 +57,9 @@ diag_l3_vag_start(struct diag_l3_conn *d_l3_conn) { (void)diag_l2_ioctl(d_l2_conn, DIAG_IOCTL_GET_L2_DATA, (void *)&l2data); - if (diag_l2_debug & DIAG_DEBUG_INIT) { - fprintf(stderr, FLFMT "start L2 KB 0x%X 0x%X need 0x01 0x8A\n", - FL, l2data.kb1, l2data.kb2); + if (diag_l2_debug_load() & DIAG_DEBUG_INIT) { + fprintf(stderr, FLFMT "start L2 KB 0x%X 0x%X need 0x01 0x8A\n", FL, + l2data.kb1, l2data.kb2); } if (l2data.kb1 != 0x01) { @@ -76,14 +76,13 @@ diag_l3_vag_start(struct diag_l3_conn *d_l3_conn) { return 0; } - /* * This is called without just the VW protocol data */ void -diag_l3_vag_decode(UNUSED(struct diag_l3_conn *d_l3_conn), -struct diag_msg *msg, char *buf, size_t bufsize) { +diag_l3_vag_decode(UNUSED(struct diag_l3_conn *d_l3_conn), struct diag_msg *msg, char *buf, + size_t bufsize) { char buf2[128]; char buf3[16]; const char *s; @@ -120,7 +119,7 @@ struct diag_msg *msg, char *buf, size_t bufsize) { snprintf(buf2, sizeof(buf2), "Data : "); smartcat(buf, bufsize, buf2); - for (int i=3; i < msg->data[0]; i++) { + for (int i = 3; i < msg->data[0]; i++) { snprintf(buf2, sizeof(buf2), "0x%X ", msg->data[i]); smartcat(buf, bufsize, buf2); } @@ -135,8 +134,8 @@ const struct diag_l3_proto diag_l3_vag = { diag_l3_base_stop, diag_l3_base_send, diag_l3_base_recv, - NULL, //ioctl + NULL, // ioctl diag_l3_base_request, diag_l3_vag_decode, - NULL //timer + NULL // timer }; diff --git a/scantool/diag_l3_vag.h b/scantool/diag_l3_vag.h index a43ce36c..659ca5e4 100644 --- a/scantool/diag_l3_vag.h +++ b/scantool/diag_l3_vag.h @@ -29,5 +29,5 @@ extern "C" { #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L3_VAG_H_ */ diff --git a/scantool/diag_l7.h b/scantool/diag_l7.h index 5d0f77dc..2e69cc46 100644 --- a/scantool/diag_l7.h +++ b/scantool/diag_l7.h @@ -30,17 +30,9 @@ extern "C" { #endif -enum namespace { - NS_MEMORY, - NS_ROM, - NS_ADC, - NS_LIVEDATA, - NS_LIVEDATA2, - NS_NV, - NS_FREEZE -}; +enum namespace { NS_MEMORY, NS_ROM, NS_ADC, NS_LIVEDATA, NS_LIVEDATA2, NS_NV, NS_FREEZE }; #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L7_H_ */ diff --git a/scantool/diag_l7_d2.c b/scantool/diag_l7_d2.c index d59b110b..dd85faaf 100644 --- a/scantool/diag_l7_d2.c +++ b/scantool/diag_l7_d2.c @@ -54,18 +54,16 @@ * are unknown. Request and response message formats for these services are * NOT according to KWP2000. */ -enum { - stopDiagnosticSession = 0xA0, - testerPresent = 0xA1, - readDataByLocalIdentifier = 0xA5, - readDataByLongLocalIdentifier = 0xA6, /* CAN bus only? */ - readMemoryByAddress = 0xA7, - readFreezeFrameByDTC = 0xAD, - readDiagnosticTroubleCodes = 0xAE, - clearDiagnosticInformation = 0xAF, - inputOutputControlByLocalIdentifier = 0xB0, - readNVByLocalIdentifier = 0xB9 -} service_id; +enum { stopDiagnosticSession = 0xA0, + testerPresent = 0xA1, + readDataByLocalIdentifier = 0xA5, + readDataByLongLocalIdentifier = 0xA6, /* CAN bus only? */ + readMemoryByAddress = 0xA7, + readFreezeFrameByDTC = 0xAD, + readDiagnosticTroubleCodes = 0xAE, + clearDiagnosticInformation = 0xAF, + inputOutputControlByLocalIdentifier = 0xB0, + readNVByLocalIdentifier = 0xB9 } service_id; /* * Indicates whether a response was a positive acknowledgement of the request. @@ -92,7 +90,7 @@ success_p(struct diag_msg *req, struct diag_msg *resp) { */ int diag_l7_d2_ping(struct diag_l2_conn *d_l2_conn) { - uint8_t req[] = { testerPresent }; + uint8_t req[] = {testerPresent}; int errval = 0; struct diag_msg msg = {0}; struct diag_msg *resp = NULL; @@ -117,10 +115,10 @@ diag_l7_d2_ping(struct diag_l2_conn *d_l2_conn) { /* The request message for reading memory */ static int read_MEMORY_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, uint8_t count) { - static uint8_t req[] = { readMemoryByAddress, 0, 99, 99, 1, 99 }; + static uint8_t req[] = {readMemoryByAddress, 0, 99, 99, 1, 99}; - req[2] = (addr>>8)&0xff; - req[3] = addr&0xff; + req[2] = (addr >> 8) & 0xff; + req[3] = addr & 0xff; req[5] = count; *msgout = req; *msglen = sizeof(req); @@ -129,10 +127,11 @@ read_MEMORY_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, uint8_t c /* The request message for reading live data by 1-byte identifier */ static int -read_LIVEDATA_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, UNUSED(uint8_t count)) { - static uint8_t req[] = { readDataByLocalIdentifier, 99, 1 }; +read_LIVEDATA_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, + UNUSED(uint8_t count)) { + static uint8_t req[] = {readDataByLocalIdentifier, 99, 1}; - req[1] = addr&0xff; + req[1] = addr & 0xff; if (addr > 0xff) { fprintf(stderr, FLFMT "read_LIVEDATA_req invalid address %x\n", FL, addr); return DIAG_ERR_GENERAL; @@ -145,10 +144,11 @@ read_LIVEDATA_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, UNUSED( /* The request message for reading live data by 2-byte ident (CAN bus only?) */ static int -read_LIVEDATA2_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, UNUSED(uint8_t count)) { - static uint8_t req[] = { readDataByLongLocalIdentifier, 99, 99, 1 }; - req[1] = (addr>>8)&0xff; - req[2] = addr&0xff; +read_LIVEDATA2_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, + UNUSED(uint8_t count)) { + static uint8_t req[] = {readDataByLongLocalIdentifier, 99, 99, 1}; + req[1] = (addr >> 8) & 0xff; + req[2] = addr & 0xff; *msgout = req; *msglen = sizeof(req); return 0; @@ -157,9 +157,9 @@ read_LIVEDATA2_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, UNUSED /* The request message for reading non-volatile data */ static int read_NV_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, UNUSED(uint8_t count)) { - static uint8_t req[] = { readNVByLocalIdentifier, 99 }; + static uint8_t req[] = {readNVByLocalIdentifier, 99}; - req[1] = addr&0xff; + req[1] = addr & 0xff; if (addr > 0xff) { fprintf(stderr, FLFMT "read_NV_req invalid address %x\n", FL, addr); return DIAG_ERR_GENERAL; @@ -172,10 +172,11 @@ read_NV_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, UNUSED(uint8_ /* The request message for reading freeze frames */ static int -read_FREEZE_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, UNUSED(uint8_t count)) { - static uint8_t req[] = { readFreezeFrameByDTC, 99, 0 }; +read_FREEZE_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, + UNUSED(uint8_t count)) { + static uint8_t req[] = {readFreezeFrameByDTC, 99, 0}; - req[1] = addr&0xff; + req[1] = addr & 0xff; if (addr > 0xff) { fprintf(stderr, FLFMT "read_FREEZE_req invalid address %x\n", FL, addr); return DIAG_ERR_GENERAL; @@ -199,7 +200,8 @@ read_FREEZE_req(uint8_t **msgout, unsigned int *msglen, uint16_t addr, UNUSED(ui * be more or less than the number of bytes requested. */ int -diag_l7_d2_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t addr, int buflen, uint8_t *out) { +diag_l7_d2_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t addr, + int buflen, uint8_t *out) { struct diag_msg req = {0}; struct diag_msg *resp = NULL; int datalen; @@ -235,25 +237,25 @@ diag_l7_d2_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t addr return rv; } - if (resp->len<2 || !success_p(&req, resp)) { + if (resp->len < 2 || !success_p(&req, resp)) { diag_freemsg(resp); return DIAG_ERR_ECUSAIDNO; } - if (ns==NS_MEMORY) { - if (resp->len!=(unsigned int)buflen+4 || memcmp(req.data+1, resp->data+1, 3)!=0) { + if (ns == NS_MEMORY) { + if (resp->len != (unsigned int)buflen + 4 || + memcmp(req.data + 1, resp->data + 1, 3) != 0) { diag_freemsg(resp); return DIAG_ERR_ECUSAIDNO; } - memcpy(out, resp->data+4, buflen); + memcpy(out, resp->data + 4, buflen); diag_freemsg(resp); return buflen; } datalen = resp->len - 2; if (datalen > 0) { - memcpy(out, resp->data + 2, - (datalen > buflen) ? buflen : datalen); + memcpy(out, resp->data + 2, (datalen > buflen) ? buflen : datalen); } diag_freemsg(resp); return datalen; @@ -264,7 +266,7 @@ diag_l7_d2_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t addr */ int diag_l7_d2_dtclist(struct diag_l2_conn *d_l2_conn, int buflen, uint8_t *out) { - uint8_t req[] = { readDiagnosticTroubleCodes, 1 }; + uint8_t req[] = {readDiagnosticTroubleCodes, 1}; int errval = 0; struct diag_msg msg = {0}; struct diag_msg *resp = NULL; @@ -278,13 +280,13 @@ diag_l7_d2_dtclist(struct diag_l2_conn *d_l2_conn, int buflen, uint8_t *out) { return errval; } - if (resp->len<2 || !success_p(&msg, resp)) { + if (resp->len < 2 || !success_p(&msg, resp)) { diag_freemsg(resp); return DIAG_ERR_ECUSAIDNO; } count = resp->len - 2; - memcpy(out, resp->data+2, (buflendata + 2, (buflen < count) ? buflen : count); if (resp->len == 14) { /* @@ -309,7 +311,7 @@ diag_l7_d2_dtclist(struct diag_l2_conn *d_l2_conn, int buflen, uint8_t *out) { */ int diag_l7_d2_cleardtc(struct diag_l2_conn *d_l2_conn) { - uint8_t req[] = { clearDiagnosticInformation, 1 }; + uint8_t req[] = {clearDiagnosticInformation, 1}; uint8_t buf[1]; struct diag_msg msg = {0}; struct diag_msg *resp = NULL; @@ -334,7 +336,7 @@ diag_l7_d2_cleardtc(struct diag_l2_conn *d_l2_conn) { return rv; } - if (resp->len==2 && success_p(&msg, resp)) { + if (resp->len == 2 && success_p(&msg, resp)) { diag_freemsg(resp); return 1; } @@ -352,7 +354,7 @@ diag_l7_d2_cleardtc(struct diag_l2_conn *d_l2_conn) { */ int diag_l7_d2_io_control(struct diag_l2_conn *d_l2_conn, uint8_t id, uint8_t reps) { - uint8_t req[] = { inputOutputControlByLocalIdentifier, id, 0x32, reps }; + uint8_t req[] = {inputOutputControlByLocalIdentifier, id, 0x32, reps}; struct diag_msg msg = {0}; struct diag_msg *resp = NULL; int rv; @@ -364,7 +366,7 @@ diag_l7_d2_io_control(struct diag_l2_conn *d_l2_conn, uint8_t id, uint8_t reps) return rv; } - if (resp->len==2 && success_p(&msg, resp)) { + if (resp->len == 2 && success_p(&msg, resp)) { diag_freemsg(resp); return 0; } diff --git a/scantool/diag_l7_d2.h b/scantool/diag_l7_d2.h index d43b5f74..e35e9f13 100644 --- a/scantool/diag_l7_d2.h +++ b/scantool/diag_l7_d2.h @@ -37,12 +37,13 @@ extern "C" { #include "diag_l7.h" int diag_l7_d2_ping(struct diag_l2_conn *d_l2_conn); -int diag_l7_d2_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t addr, int buflen, uint8_t *out); +int diag_l7_d2_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t addr, + int buflen, uint8_t *out); int diag_l7_d2_dtclist(struct diag_l2_conn *d_l2_conn, int buflen, uint8_t *out); int diag_l7_d2_cleardtc(struct diag_l2_conn *d_l2_conn); int diag_l7_d2_io_control(struct diag_l2_conn *d_l2_conn, uint8_t id, uint8_t reps); #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L7_D2_H_ */ diff --git a/scantool/diag_l7_kwp71.c b/scantool/diag_l7_kwp71.c index 5e4471cc..1e167edd 100644 --- a/scantool/diag_l7_kwp71.c +++ b/scantool/diag_l7_kwp71.c @@ -95,15 +95,16 @@ diag_l7_kwp71_ping(struct diag_l2_conn *d_l2_conn) { /* The request message for reading memory */ static int -read_MEMORY_req(struct diag_msg **msgout, uint8_t *wantresp, uint16_t addr, uint8_t count) { - static struct diag_msg msg = { 0 }; +read_MEMORY_req(struct diag_msg **msgout, uint8_t *wantresp, uint16_t addr, + uint8_t count) { + static struct diag_msg msg = {0}; static uint8_t data[3]; msg.type = readMemoryByAddress; msg.len = 3; data[0] = count; - data[1] = (addr>>8)&0xff; - data[2] = addr&0xff; + data[1] = (addr >> 8) & 0xff; + data[2] = addr & 0xff; msg.data = data; *msgout = &msg; *wantresp = readMemoryByAddress_resp; @@ -113,14 +114,14 @@ read_MEMORY_req(struct diag_msg **msgout, uint8_t *wantresp, uint16_t addr, uint /* The request message for reading ROM */ static int read_ROM_req(struct diag_msg **msgout, uint8_t *wantresp, uint16_t addr, uint8_t count) { - static struct diag_msg msg = { 0 }; + static struct diag_msg msg = {0}; static uint8_t data[3]; msg.type = readROMByAddress; msg.len = 3; data[0] = count; - data[1] = (addr>>8)&0xff; - data[2] = addr&0xff; + data[1] = (addr >> 8) & 0xff; + data[2] = addr & 0xff; msg.data = data; *msgout = &msg; *wantresp = readROMByAddress_resp; @@ -130,7 +131,7 @@ read_ROM_req(struct diag_msg **msgout, uint8_t *wantresp, uint16_t addr, uint8_t /* The request message for taking ADC readings */ static int read_ADC_req(struct diag_msg **msgout, uint8_t *wantresp, uint16_t addr) { - static struct diag_msg msg = { 0 }; + static struct diag_msg msg = {0}; static uint8_t data[1]; if (addr > 0xff) { @@ -159,7 +160,8 @@ read_ADC_req(struct diag_msg **msgout, uint8_t *wantresp, uint16_t addr) { * bytes requested. Returns the actual byte count received. */ int -diag_l7_kwp71_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t addr, int buflen, uint8_t *out) { +diag_l7_kwp71_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t addr, + int buflen, uint8_t *out) { struct diag_msg *req; struct diag_msg *resp = NULL; uint8_t wantresp; @@ -189,12 +191,12 @@ diag_l7_kwp71_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t a return rv; } - if (resp->type!=wantresp) { + if (resp->type != wantresp) { diag_freemsg(resp); return DIAG_ERR_ECUSAIDNO; } - if (ns==NS_ADC && resp->len!=2) { + if (ns == NS_ADC && resp->len != 2) { diag_freemsg(resp); return DIAG_ERR_ECUSAIDNO; } @@ -202,8 +204,9 @@ diag_l7_kwp71_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t a diag_freemsg(resp); return DIAG_ERR_ECUSAIDNO; } - memcpy(out, resp->data, (resp->len>(unsigned int)buflen)?(unsigned int)buflen:resp->len); - rv = (resp->len > (unsigned int)buflen) ? (unsigned int)buflen:resp->len; + memcpy(out, resp->data, + (resp->len > (unsigned int)buflen) ? (unsigned int)buflen : resp->len); + rv = (resp->len > (unsigned int)buflen) ? (unsigned int)buflen : resp->len; diag_freemsg(resp); return rv; } @@ -232,7 +235,7 @@ diag_l7_kwp71_dtclist(struct diag_l2_conn *d_l2_conn, int buflen, uint8_t *out) count = resp->len; - if (resp->type!=readDiagnosticTroubleCodes_resp) { + if (resp->type != readDiagnosticTroubleCodes_resp) { diag_freemsg(resp); return DIAG_ERR_ECUSAIDNO; } @@ -252,7 +255,7 @@ diag_l7_kwp71_dtclist(struct diag_l2_conn *d_l2_conn, int buflen, uint8_t *out) * responses. For now, we only look at the DTCs in the first * response. */ - fprintf(stderr, "Warning: retrieving only first %d DTCs\n", count/5); + fprintf(stderr, "Warning: retrieving only first %d DTCs\n", count / 5); } return count; diff --git a/scantool/diag_l7_kwp71.h b/scantool/diag_l7_kwp71.h index f5262589..20f9faa4 100644 --- a/scantool/diag_l7_kwp71.h +++ b/scantool/diag_l7_kwp71.h @@ -37,11 +37,12 @@ extern "C" { #include "diag_l7.h" int diag_l7_kwp71_ping(struct diag_l2_conn *d_l2_conn); -int diag_l7_kwp71_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t addr, int buflen, uint8_t *out); +int diag_l7_kwp71_read(struct diag_l2_conn *d_l2_conn, enum namespace ns, uint16_t addr, + int buflen, uint8_t *out); int diag_l7_kwp71_dtclist(struct diag_l2_conn *d_l2_conn, int buflen, uint8_t *out); int diag_l7_kwp71_cleardtc(struct diag_l2_conn *d_l2_conn); #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_L7_KWP71_H_ */ diff --git a/scantool/diag_mb1.h b/scantool/diag_mb1.h index 6d4b4a80..02cfdecb 100644 --- a/scantool/diag_mb1.h +++ b/scantool/diag_mb1.h @@ -30,16 +30,16 @@ extern "C" { #endif -#define DIAG_MB1_GETDTC 0x05 /* Get Diagnostic Trouble Codes */ -#define DIAG_MB1_GETID 0x0f /* Ask for controller/hw/sw version */ -#define DIAG_MB1_UNKNOWN1 0x10 /* Dunno yet */ -#define DIAG_MB1_UNKNOWN2 0x30 /* Dunno yet */ -#define DIAG_MB1_UNKNOWN3 0x38 /* Dunno yet */ -#define DIAG_MB1_IDLE 0x50 /* Idle message */ +#define DIAG_MB1_GETDTC 0x05 /* Get Diagnostic Trouble Codes */ +#define DIAG_MB1_GETID 0x0f /* Ask for controller/hw/sw version */ +#define DIAG_MB1_UNKNOWN1 0x10 /* Dunno yet */ +#define DIAG_MB1_UNKNOWN2 0x30 /* Dunno yet */ +#define DIAG_MB1_UNKNOWN3 0x38 /* Dunno yet */ +#define DIAG_MB1_IDLE 0x50 /* Idle message */ -#define DIAG_MB1_ANSWER_MASK 0x80 /* Bit set for answers */ +#define DIAG_MB1_ANSWER_MASK 0x80 /* Bit set for answers */ #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_MB1_H_ */ diff --git a/scantool/diag_os.h b/scantool/diag_os.h index 3ccc64c8..694d363f 100644 --- a/scantool/diag_os.h +++ b/scantool/diag_os.h @@ -35,19 +35,19 @@ extern "C" { #include #ifdef WIN32 - #include - typedef DWORD OS_ERRTYPE; +# include +typedef DWORD OS_ERRTYPE; #else - typedef int OS_ERRTYPE; +typedef int OS_ERRTYPE; #endif -#define ALARM_TIMEOUT 300 // ms interval timeout for timer callbacks (keepalive etc) +#define ALARM_TIMEOUT 300 // ms interval timeout for timer callbacks (keepalive etc) /* Common prototypes but note that the source * is different and defined in OS specific * c files. */ -//init, close : ret 0 if ok +// init, close : ret 0 if ok int diag_os_init(void); int diag_os_close(void); @@ -63,9 +63,9 @@ void diag_os_millisleep(unsigned int ms); * * @return 0 if no key was pressed * - * Currently, it is only used in a few places to break long loops, with "press any key to stop" semantics. - * This returns immediately, to allow polling within a loop. - * The linux/unix implementation needs an "Enter" keypress since stdin is buffered ! + * Currently, it is only used in a few places to break long loops, with "press any key to + * stop" semantics. This returns immediately, to allow polling within a loop. The + * linux/unix implementation needs an "Enter" keypress since stdin is buffered ! */ int diag_os_ipending(void); @@ -119,12 +119,28 @@ unsigned long long diag_os_hrtus(unsigned long long hrdelta); * the backends use pthread, C11, winAPI etc. * lowest-common-denominator stuff here; regular mutexes (not necessarily recursive etc) */ -typedef void diag_mtx; +#if defined(_WIN32) +# include +// No static mutex initialization on Windows. +# define LOCK_INITIALIZER 0 +typedef CRITICAL_SECTION diag_mtx; +#elif defined(__unix__) +# include +# define LOCK_INITIALIZER PTHREAD_MUTEX_INITIALIZER +typedef pthread_mutex_t diag_mtx; +#else +# error Weird compilation environment, report this! +#endif -/** return a ptr to a new, initialized mutex. +/** initialize mutex. * must be deleted with diag_os_delmtx() after use */ -diag_mtx *diag_os_newmtx(void); +void diag_os_initmtx(diag_mtx *mtx); + +/** initialize mutex statically initialized with LOCK_INITIALIZER. + * must be deleted with diag_os_delmtx() after use + */ +void diag_os_initstaticmtx(diag_mtx *mtx); /** delete unused mutex */ @@ -139,8 +155,7 @@ bool diag_os_trylock(diag_mtx *mtx); /** unlock mutex */ void diag_os_unlock(diag_mtx *mtx); - #if defined(__cplusplus) } -#endif +# endif #endif /*_DIAG_OS_H_ */ diff --git a/scantool/diag_os_unix.c b/scantool/diag_os_unix.c index 1dea6b17..305b309d 100644 --- a/scantool/diag_os_unix.c +++ b/scantool/diag_os_unix.c @@ -39,8 +39,9 @@ * * Goals : if _POSIX_TIMERS is defined, we attempt to use: * 1- POSIX timer_create() mechanisms for the periodic callbacks - * 2- POSIX clock_gettime(), using best available clockid, for _getms() and _gethrt() - * 3- clock_nanosleep(), using best available clockid, for _millisleep() + * 2- POSIX clock_gettime(), using best available clockid, for _getms() and + _gethrt() * 3- clock_nanosleep(), using best available clockid, for + _millisleep() * * Fallbacks for above: * 1- SIGALRM signal handler @@ -49,13 +50,13 @@ * 3b- (other): nanosleep() * * more info on different OS high-resolution timers: - * http://nadeausoftware.com/articles/2012/04/c_c_tip_how_measure_elapsed_real_time_benchmarking + * + http://nadeausoftware.com/articles/2012/04/c_c_tip_how_measure_elapsed_real_time_benchmarking * * TODO: diag_os_sched non-root fallback ? (i.e. highest prio available to uid!=0) */ - #include #include #include @@ -83,60 +84,61 @@ * interfere with each other (ex. if both _POSIX_TIMERS && __linux__ ) */ #ifdef _POSIX_TIMERS - /* This should be defined on a lot of linux/unix systems. - Implications : timer_create(), clock_gettime(), clock_nanosleep() are available. - */ - //Best clockids auto-selected by diag_os_discover() : - static clockid_t clkid_pt = CLOCK_MONOTONIC; //clockid for periodic timer, - static clockid_t clkid_gt = CLOCK_MONOTONIC; // for clock_gettime(), - static clockid_t clkid_ns = CLOCK_MONOTONIC; // for clock_nanosleep() +/* This should be defined on a lot of linux/unix systems. + Implications : timer_create(), clock_gettime(), clock_nanosleep() are available. +*/ +// Best clockids auto-selected by diag_os_discover() : +static clockid_t clkid_pt = CLOCK_MONOTONIC; // clockid for periodic timer, +static clockid_t clkid_gt = CLOCK_MONOTONIC; // for clock_gettime(), +static clockid_t clkid_ns = CLOCK_MONOTONIC; // for clock_nanosleep() - static timer_t ptimer_id; //periodic timer ID -#endif // _POSIX_TIMERS +static timer_t ptimer_id; // periodic timer ID +#endif // _POSIX_TIMERS #ifdef __linux__ - #include //need these for - #include //diag_os_millisleep fallback -#ifndef _POSIX_TIMERS - #warning ****** WARNING ! Linux without _POSIX_TIMERS ?? Please report this ! -#endif +# include //need these for +# include //diag_os_millisleep fallback +# ifndef _POSIX_TIMERS +# warning ****** WARNING ! Linux without _POSIX_TIMERS ?? Please report this ! +# endif #endif // __linux__ #ifdef HAVE_GETTIMEOFDAY - #include //only for gettimeofday(), timeval etc? +# include //only for gettimeofday(), timeval etc? #endif /***/ - -static int diag_os_init_done=0; -static int discover_done = 0; //protect diag_os_millisleep() and _gethrt() +static int diag_os_init_done = 0; +static int discover_done = 0; // protect diag_os_millisleep() and _gethrt() static void diag_os_discover(void); static pthread_mutex_t periodic_lock = PTHREAD_MUTEX_INITIALIZER; static void -#if defined(_POSIX_TIMERS) && (SEL_PERIODIC==S_POSIX || SEL_PERIODIC==S_AUTO) +#if defined(_POSIX_TIMERS) && (SEL_PERIODIC == S_POSIX || SEL_PERIODIC == S_AUTO) diag_os_periodic(UNUSED(union sigval sv)) { #else diag_os_periodic(UNUSED(int unused)) { #endif /* Warning: these indirectly use non-async-signal-safe functions - * Their behavior is undefined if they happen - * to occur during any other non-async-signal-safe function. - * See doc/sourcetree_notes.txt - */ - if (pthread_mutex_trylock(&periodic_lock)) { + * Their behavior is undefined if they happen + * to occur during any other non-async-signal-safe function. + * See doc/sourcetree_notes.txt + */ + + if (periodic_done() || pthread_mutex_trylock(&periodic_lock)) { return; } - diag_l3_timer(); /* Call L3 Timers */ - diag_l2_timer(); /* Call L2 timers */ + + diag_l3_timer(); /* Call L3 Timers */ + diag_l2_timer(); /* Call L2 timers */ pthread_mutex_unlock(&periodic_lock); } -//diag_os_init sets up a periodic callback (diag_os_periodic()) -//for keepalive messages, and selects + calibrates timer functions. -//return 0 if ok +// diag_os_init sets up a periodic callback (diag_os_periodic()) +// for keepalive messages, and selects + calibrates timer functions. +// return 0 if ok int diag_os_init(void) { const long tmo = ALARM_TIMEOUT; @@ -145,27 +147,30 @@ diag_os_init(void) { return 0; } - diag_os_discover(); //auto-select clockids or other capabilities - diag_os_calibrate(); //calibrate before starting periodic timer + diag_os_discover(); // auto-select clockids or other capabilities + diag_os_calibrate(); // calibrate before starting periodic timer -#if defined(_POSIX_TIMERS) && (SEL_PERIODIC==S_POSIX || SEL_PERIODIC==S_AUTO) +#if defined(_POSIX_TIMERS) && (SEL_PERIODIC == S_POSIX || SEL_PERIODIC == S_AUTO) struct itimerspec pti; struct sigevent pt_sigev; - pt_sigev.sigev_notify = SIGEV_THREAD; //"Upon timer expiration, invoke sigev_notify_function " + pt_sigev.sigev_notify = SIGEV_THREAD; //"Upon timer expiration, invoke + // sigev_notify_function " pt_sigev.sigev_notify_function = diag_os_periodic; - pt_sigev.sigev_notify_attributes = NULL; //not sure what we need here, if anything. -// pt_sigev.sigev_value.sival_int = 0; //not used -// pt_sigev.siev_signo = 0; //not used + pt_sigev.sigev_notify_attributes = NULL; // not sure what we need here, if + // anything. + // pt_sigev.sigev_value.sival_int = 0; //not used + // pt_sigev.siev_signo = 0; //not used if (timer_create(clkid_pt, &pt_sigev, &ptimer_id) != 0) { - fprintf(stderr, FLFMT "Could not create periodic timer... report this\n", FL); + fprintf(stderr, FLFMT "Could not create periodic timer... report this\n", + FL); diag_os_geterr(0); return diag_iseterr(DIAG_ERR_GENERAL); } - //timer was created in disarmed state + // timer was created in disarmed state pti.it_interval.tv_sec = (tmo / 1000); - pti.it_interval.tv_nsec = (tmo % 1000) * 1000*1000; + pti.it_interval.tv_nsec = (tmo % 1000) * 1000 * 1000; pti.it_value.tv_sec = pti.it_interval.tv_sec; pti.it_value.tv_nsec = pti.it_interval.tv_nsec; @@ -175,7 +180,7 @@ diag_os_init(void) { timer_delete(ptimer_id); return diag_iseterr(DIAG_ERR_GENERAL); } -#else //so, no _POSIX_TIMERS ... sucks +#else // so, no _POSIX_TIMERS ... sucks struct sigaction stNew; struct itimerval tv; @@ -185,41 +190,41 @@ diag_os_init(void) { memset(&stNew, 0, sizeof(stNew)); stNew.sa_handler = diag_os_periodic; stNew.sa_flags = 0; - //stNew.sa_flags = SA_RESTART; - -/* Notes on SA_RESTART: (man 7 signal) - The following interfaces are never restarted after being interrupted by - a signal handler, regardless of the use of SA_RESTART; they always fail - with the error EINTR when interrupted by a signal handler: - select, clock_nanosleep, [some others]. - -*** From POSIX docs: - SA_RESTART - This flag affects the behavior of interruptible functions; that is, - those specified to fail with errno set to [EINTR]. If set, and a - function specified as interruptible is interrupted by this signal, - the function shall restart and shall not fail with [EINTR] unless - otherwise specified. If an interruptible function which uses a - timeout is restarted, the duration of the timeout following the - restart is set to an unspecified value that does not exceed the - original timeout value. If the flag is not set, interruptible - functions interrupted by this signal shall fail with errno set to - [EINTR]. - -*** Interesting synthesis on - http://unix.stackexchange.com/questions/16455/interruption-of-system-calls-when-a-signal-is-caught - -*** Conclusion : since we need to handle EINTR for read(), write(), select() - and some *sleep() syscalls anyway, we don't specify SA_RESTART. + // stNew.sa_flags = SA_RESTART; + + /* Notes on SA_RESTART: (man 7 signal) + The following interfaces are never restarted after being interrupted by + a signal handler, regardless of the use of SA_RESTART; they always fail + with the error EINTR when interrupted by a signal handler: + select, clock_nanosleep, [some others]. + + *** From POSIX docs: + SA_RESTART + This flag affects the behavior of interruptible functions; that is, + those specified to fail with errno set to [EINTR]. If set, and a + function specified as interruptible is interrupted by this signal, + the function shall restart and shall not fail with [EINTR] unless + otherwise specified. If an interruptible function which uses a + timeout is restarted, the duration of the timeout following the + restart is set to an unspecified value that does not exceed the + original timeout value. If the flag is not set, interruptible + functions interrupted by this signal shall fail with errno set to + [EINTR]. + + *** Interesting synthesis on + http://unix.stackexchange.com/questions/16455/interruption-of-system-calls-when-a-signal-is-caught + + *** Conclusion : since we need to handle EINTR for read(), write(), select() + and some *sleep() syscalls anyway, we don't specify SA_RESTART. -*/ + */ - sigaction(SIGALRM, &stNew, NULL); //install handler for SIGALRM + sigaction(SIGALRM, &stNew, NULL); // install handler for SIGALRM /* * Start repeating timer */ - tv.it_interval.tv_sec = tmo / 1000; /* Seconds */ - tv.it_interval.tv_usec = (tmo % 1000) * 1000; /* ms */ + tv.it_interval.tv_sec = tmo / 1000; /* Seconds */ + tv.it_interval.tv_usec = (tmo % 1000) * 1000; /* ms */ tv.it_value = tv.it_interval; @@ -228,81 +233,81 @@ diag_os_init(void) { diag_os_init_done = 1; return 0; -} //diag_os_init +} // diag_os_init -//diag_os_close: delete alarm handlers / periodic timers -//return 0 if ok (in this case, always) -int diag_os_close() { -#if defined(_POSIX_TIMERS) && (SEL_PERIODIC==S_POSIX || SEL_PERIODIC==S_AUTO) - //disarm + delete periodic timer +// diag_os_close: delete alarm handlers / periodic timers +// return 0 if ok (in this case, always) +int +diag_os_close() { +#if defined(_POSIX_TIMERS) && (SEL_PERIODIC == S_POSIX || SEL_PERIODIC == S_AUTO) + // disarm + delete periodic timer timer_delete(ptimer_id); #else - //stop the interval timer: - struct itimerval tv = {{0,0},{0, 0}}; + // stop the interval timer: + struct itimerval tv = {{0, 0}, {0, 0}}; setitimer(ITIMER_REAL, &tv, 0); - //and set the SIGALRM handler to default, whatever that is + // and set the SIGALRM handler to default, whatever that is struct sigaction disable_tmr; memset(&disable_tmr, 0, sizeof(disable_tmr)); - disable_tmr.sa_handler=SIG_DFL; + disable_tmr.sa_handler = SIG_DFL; sigaction(SIGALRM, &disable_tmr, NULL); #endif // _POSIX_TIMERS diag_os_init_done = 0; return 0; -} //diag_os_close +} // diag_os_close - -//return after (ms) milliseconds. +// return after (ms) milliseconds. void diag_os_millisleep(unsigned int ms) { - unsigned long long t1,t2; //for verification + unsigned long long t1, t2; // for verification long int offsetus; - t1=diag_os_gethrt(); + t1 = diag_os_gethrt(); if (ms == 0 || !discover_done) { return; } -//3 different compile-time implementations -//TODO : select implem at runtime if possible? + internal feedback loop -#if defined(_POSIX_TIMERS) && (SEL_SLEEP==S_POSIX || SEL_SLEEP==S_AUTO) +// 3 different compile-time implementations +// TODO : select implem at runtime if possible? + internal feedback loop +#if defined(_POSIX_TIMERS) && (SEL_SLEEP == S_POSIX || SEL_SLEEP == S_AUTO) struct timespec rqst, resp; int rv; rqst.tv_sec = ms / 1000; - rqst.tv_nsec = (ms % 1000) * 1000*1000; + rqst.tv_nsec = (ms % 1000) * 1000 * 1000; errno = 0; - //clock_nanosleep is interruptible, hence this loop - while ((rv=clock_nanosleep(clkid_ns, 0, &rqst, &resp)) != 0) { + // clock_nanosleep is interruptible, hence this loop + while ((rv = clock_nanosleep(clkid_ns, 0, &rqst, &resp)) != 0) { if (rv == EINTR) { rqst = resp; errno = 0; } else { - //unlikely - fprintf(stderr, "diag_os_millisleep : error %d\n",rv); + // unlikely + fprintf(stderr, "diag_os_millisleep : error %d\n", rv); break; } } -#elif defined(__linux__) && (SEL_SLEEP==S_LINUX || SEL_SLEEP==S_AUTO) -/** ugly /dev/rtc implementation; requires uid=0 or appropriate permissions. **/ +#elif defined(__linux__) && (SEL_SLEEP == S_LINUX || SEL_SLEEP == S_AUTO) + /** ugly /dev/rtc implementation; requires uid=0 or appropriate permissions. **/ int fd, retval; unsigned int i; - unsigned long tmp,data; + unsigned long tmp, data; /* adjust time for 2048 rate */ - ms = (unsigned int)((unsigned long) ms* 2048/1000); //avoid overflow + ms = (unsigned int)((unsigned long)ms * 2048 / 1000); // avoid overflow - if (ms > 2) //Bias delay -1ms to avoid overshoot ? - ms-=2; + if (ms > 2) // Bias delay -1ms to avoid overshoot ? + ms -= 2; - fd = open ("/dev/rtc", O_RDONLY); + fd = open("/dev/rtc", O_RDONLY); - if (fd == -1) { + if (fd == -1) { perror("/dev/rtc"); exit(errno); } @@ -339,8 +344,8 @@ diag_os_millisleep(unsigned int ms) { exit(errno); } data >>= 8; - i += (unsigned int) data; - if (i>=(ms*2)) + i += (unsigned int)data; + if (i >= (ms * 2)) break; } @@ -354,34 +359,34 @@ diag_os_millisleep(unsigned int ms) { close(fd); #else #warning ****** WARNING ! Your system needs help. Using nanosleep() third-string backup plan. -#warning ****** Please report this! +# warning ****** Please report this! struct timespec rqst, resp; int rv; rqst.tv_sec = ms / 1000; - rqst.tv_nsec = (ms % 1000) * 1000*1000; + rqst.tv_nsec = (ms % 1000) * 1000 * 1000; errno = 0; - //clock_nanosleep is interruptible, hence this loop - while ((rv=nanosleep(&rqst, &resp)) != 0) { + // clock_nanosleep is interruptible, hence this loop + while ((rv = nanosleep(&rqst, &resp)) != 0) { if (rv == EINTR) { rqst = resp; errno = 0; } else { - break; //unlikely + break; // unlikely } } #endif // SEL_SLEEP t2 = diag_os_gethrt(); - offsetus = ((long int) diag_os_hrtus(t2-t1)) - ms*1000; + offsetus = ((long int)diag_os_hrtus(t2 - t1)) - ms * 1000; if ((offsetus > 1500) || (offsetus < -1500)) { printf("_millisleep off by %ld\n", offsetus); } return; -} //diag_os_millisleep +} // diag_os_millisleep /* * diag_os_ipending: Is input available on stdin. ret 1 if yes. @@ -394,39 +399,42 @@ diag_os_ipending(void) { int rv; struct timeval tv; - FD_ZERO(&set); // empty set of FDs; - FD_SET(fileno(stdin), &set); //adds an FD to the set + FD_ZERO(&set); // empty set of FDs; + FD_SET(fileno(stdin), &set); // adds an FD to the set tv.tv_sec = 0; - tv.tv_usec = 0; //select() with 0 timeout (return immediately) + tv.tv_usec = 0; // select() with 0 timeout (return immediately) /* * poll for input using select(): */ errno = 0; - //int select(nfds, readset, writeset, exceptset, timeout) ; return number of ready FDs found - rv = select(fileno(stdin) + 1, &set, NULL, NULL, &tv); - //this will return immediately since timeout=0. NOTE : not the same thing as passing NULL instead of &tv : - // in that case, it would NOT return until something is ready, in this case readset. - - return rv == 1 ; - + // int select(nfds, readset, writeset, exceptset, timeout) ; return number of ready + // FDs found + rv = select(fileno(stdin) + 1, &set, NULL, NULL, &tv); + // this will return immediately since timeout=0. NOTE : not the same thing as + // passing NULL instead of &tv : + // in that case, it would NOT return until something is ready, in this case + // readset. + + return rv == 1; } -//diag_os_sched : set high priority for this thread/process. -//this is called from most diag_l0_* devices; calling more than once -//will harm nothing. There is no "opposite" function of this, to -//reset normal priority. +// diag_os_sched : set high priority for this thread/process. +// this is called from most diag_l0_* devices; calling more than once +// will harm nothing. There is no "opposite" function of this, to +// reset normal priority. int diag_os_sched(void) { - static int os_sched_done=0; - int rv=0; + static int os_sched_done = 0; + int rv = 0; if (os_sched_done) { return 0; } -#if defined(_POSIX_PRIORITY_SCHEDULING) && (SEL_SCHED==S_POSIX || SEL_SCHED==S_LINUX || SEL_SCHED==S_AUTO) -#include +#if defined(_POSIX_PRIORITY_SCHEDULING) && \ + (SEL_SCHED == S_POSIX || SEL_SCHED == S_LINUX || SEL_SCHED == S_AUTO) +# include /* * Check privileges */ @@ -435,68 +443,69 @@ diag_os_sched(void) { if (suser_warned == 0) { suser_warned = 1; fprintf(stderr, - FLFMT "WARNING: Not running as superuser; " - "things may not work correctly\n", FL); + FLFMT + "WARNING: Not running as superuser; " + "things may not work correctly\n", + FL); } } -#if defined(__linux__) && (SEL_SCHED==S_LINUX || SEL_SCHED==S_AUTO) +# if defined(__linux__) && (SEL_SCHED == S_LINUX || SEL_SCHED == S_AUTO) { - int r=0; + int r = 0; struct sched_param p; /* Set real time UNIX scheduling */ p.sched_priority = 1; - if ( sched_setscheduler(getpid(), SCHED_FIFO, &p) < 0) { - fprintf(stderr, FLFMT "sched_setscheduler failed: %s.\n", - FL, strerror(errno)); + if (sched_setscheduler(getpid(), SCHED_FIFO, &p) < 0) { + fprintf(stderr, FLFMT "sched_setscheduler failed: %s.\n", FL, + strerror(errno)); r = -1; } - rv=r; + rv = r; } -#else +# else /* +* If we're not running on Linux, we're not sure if what is +* being done is remotely applicable for our flavor of POSIX +* priority scheduling. +* For example, you set the scheduling priority to 1. Ouch. */ -#warning Scheduling setup should be examined on your particular platform ! -#warning Please report this ! +# warning Scheduling setup should be examined on your particular platform ! +# warning Please report this ! fprintf(stderr, FLFMT "Scheduling setup should be examined.\n", FL); rv = 0; -#endif // __linux__ +# endif // __linux__ -#else //not POSIX_PRIO_SCHED -#warning No special scheduling support in diag_os.c for your OS! Please report this ! +#else // not POSIX_PRIO_SCHED +# warning No special scheduling support in diag_os.c for your OS! Please report this ! - fprintf(stderr, - FLFMT "diag_os_sched: No special scheduling support.\n", FL); - rv=0; + fprintf(stderr, FLFMT "diag_os_sched: No special scheduling support.\n", FL); + rv = 0; #endif // _POSIX_PRIORITY_SCHEDULING - os_sched_done=1; + os_sched_done = 1; return rv; -} //of diag_os_sched +} // of diag_os_sched - -//diag_os_geterr : get OS-specific error string. -//Either gets the last error if os_errno==0, or print the -//message associated with the specified os_errno +// diag_os_geterr : get OS-specific error string. +// Either gets the last error if os_errno==0, or print the +// message associated with the specified os_errno // XXX this is not async-safe / re-entrant ! -const char *diag_os_geterr(OS_ERRTYPE os_errno) { - //we'll suppose strerr is satisfactory. - return (const char *) strerror(os_errno? os_errno : errno); -// static char errbuf[30]; - -// snprintf(errbuf, sizeof(errbuf), "OS Error %d", os_errno); -// return (const char *) errbuf; - +const char * +diag_os_geterr(OS_ERRTYPE os_errno) { + // we'll suppose strerr is satisfactory. + return (const char *)strerror(os_errno ? os_errno : errno); + // static char errbuf[30]; + + // snprintf(errbuf, sizeof(errbuf), "OS Error %d", os_errno); + // return (const char *) errbuf; } #ifdef _POSIX_TIMERS -//internal use. ret 0 if ok -static int diag_os_testgt(clockid_t ckid, char *ckname) { +// internal use. ret 0 if ok +static int +diag_os_testgt(clockid_t ckid, char *ckname) { struct timespec tmtest; if (clock_gettime(ckid, &tmtest) == 0) { printf("clock_gettime(): using %s\n", ckname); @@ -505,11 +514,12 @@ static int diag_os_testgt(clockid_t ckid, char *ckname) { } return -1; } -//internal use. ret 0 if ok -static int diag_os_testns(clockid_t ckid, char *ckname) { +// internal use. ret 0 if ok +static int +diag_os_testns(clockid_t ckid, char *ckname) { struct timespec rqtp; rqtp.tv_sec = 0; - rqtp.tv_nsec = 0; //bogus interval for nanosleep test + rqtp.tv_nsec = 0; // bogus interval for nanosleep test if (clock_nanosleep(ckid, 0, &rqtp, NULL) != ENOTSUP) { printf("clock_nanosleep(): using %s\n", ckname); clkid_ns = ckid; @@ -519,47 +529,55 @@ static int diag_os_testns(clockid_t ckid, char *ckname) { } #endif // _POSIX_TIMERS -//use best clock truly available: -//TODO : add weird clockids for other systems -static void diag_os_discover(void) { -#ifdef _POSIX_TIMERS //this guarantees clock_gettime and CLOCK_REALTIME are available - int gtdone=0, nsdone=0; - -// ***** 1) set clockid for periodic timers -#ifdef _POSIX_MONOTONIC_CLOCK - //for some reason we can't use CLOCK_MONOTONIC_RAW, but - //CLOCK_MONOTONIC will do just fine - clkid_pt= CLOCK_MONOTONIC; -#else - //CLOCK_REALTIME is mandatory (_MONOTONIC was optional) +// use best clock truly available: +// TODO : add weird clockids for other systems +static void +diag_os_discover(void) { +#ifdef _POSIX_TIMERS // this guarantees clock_gettime and CLOCK_REALTIME are available + int gtdone = 0, nsdone = 0; + + // ***** 1) set clockid for periodic timers +# ifdef _POSIX_MONOTONIC_CLOCK + // for some reason we can't use CLOCK_MONOTONIC_RAW, but + // CLOCK_MONOTONIC will do just fine + clkid_pt = CLOCK_MONOTONIC; +# else + // CLOCK_REALTIME is mandatory (_MONOTONIC was optional) clkid_pt = CLOCK_REALTIME; -#endif // _POSIX_MONOTONIC_CLOCK - -// ***** 2) test clockids for clock_gettime and clock_nanosleep -#define TESTCK(X) if (!gtdone) if (diag_os_testgt(X, #X)==0) { gtdone=1;} \ - if (!nsdone) if (diag_os_testns(X, #X)==0) { nsdone=1;} +# endif // _POSIX_MONOTONIC_CLOCK + + // ***** 2) test clockids for clock_gettime and clock_nanosleep +# define TESTCK(X) \ + if (!gtdone) \ + if (diag_os_testgt(X, #X) == 0) { \ + gtdone = 1; \ + } \ + if (!nsdone) \ + if (diag_os_testns(X, #X) == 0) { \ + nsdone = 1; \ + } -#ifdef CLOCK_MONOTONIC_RAW +# ifdef CLOCK_MONOTONIC_RAW TESTCK(CLOCK_MONOTONIC_RAW) -#endif // CLOCK_MONOTONIC_RAW -#ifdef CLOCK_MONOTONIC +# endif // CLOCK_MONOTONIC_RAW +# ifdef CLOCK_MONOTONIC TESTCK(CLOCK_MONOTONIC) -#endif // CLOCK_MONOTONIC -#ifdef CLOCK_BOOTTIME +# endif // CLOCK_MONOTONIC +# ifdef CLOCK_BOOTTIME TESTCK(CLOCK_BOOTTIME) if (clkid_gt == CLOCK_BOOTTIME) { printf("CLOCK_BOOTTIME is unusual...\n"); } -#endif // CLOCK_BOOTTIME -#ifdef CLOCK_REALTIME +# endif // CLOCK_BOOTTIME +# ifdef CLOCK_REALTIME TESTCK(CLOCK_REALTIME) if (clkid_gt == CLOCK_REALTIME) { printf("CLOCK_REALTIME is suboptimal !\n"); } -#endif -// ***** 3) report possible problems +# endif + // ***** 3) report possible problems if (!gtdone) { - clkid_gt = CLOCK_REALTIME; //won't work anyway... + clkid_gt = CLOCK_REALTIME; // won't work anyway... printf("WARNING: no clockid for clock_gettime()!!\n"); } if (!nsdone) { @@ -567,24 +585,25 @@ static void diag_os_discover(void) { printf("WARNING: no clockid for clock_nanosleep()!!\n"); } if (!gtdone || !nsdone) { - printf("WARNING: your system lied about its clocks;\nWARNING: you WILL have problems !\n"); + printf("WARNING: your system lied about its clocks;\nWARNING: you WILL " + "have problems !\n"); } #else - //nothing to do (yet) for non-posix + // nothing to do (yet) for non-posix #endif // _POSIX_TIMERS discover_done = 1; return; } - -//diag_os_calibrate : run some timing tests to make sure we have -//adequate performances. -//call after diag_os_discover ! -void diag_os_calibrate(void) { - #define RESOL_ITERS 5 - static int calibrate_done=0; +// diag_os_calibrate : run some timing tests to make sure we have +// adequate performances. +// call after diag_os_discover ! +void +diag_os_calibrate(void) { +#define RESOL_ITERS 5 + static int calibrate_done = 0; unsigned long t1, t2; - unsigned long long tl1, tl2, resol, maxres; //for _gethrt() + unsigned long long tl1, tl2, resol, maxres; // for _gethrt() if (calibrate_done) { return; @@ -593,66 +612,70 @@ void diag_os_calibrate(void) { diag_os_discover(); } - //test _gethrt(). clock_getres() would tell us the resolution, but measuring - //like this gives a better measure of "usable" res. - resol=0; - maxres=0; - for (int i=0; i < RESOL_ITERS; i++) { + // test _gethrt(). clock_getres() would tell us the resolution, but measuring + // like this gives a better measure of "usable" res. + resol = 0; + maxres = 0; + for (int i = 0; i < RESOL_ITERS; i++) { unsigned long long tr; - tl1=diag_os_gethrt(); - while ((tl2=diag_os_gethrt()) == tl1) {} - tr = (tl2-tl1); + tl1 = diag_os_gethrt(); + while ((tl2 = diag_os_gethrt()) == tl1) { + } + tr = (tl2 - tl1); if (tr > maxres) { maxres = tr; } resol += tr; } printf("diag_os_gethrt() resolution <= %lluus, avg ~%lluus\n", - diag_os_hrtus(maxres), diag_os_hrtus(resol / RESOL_ITERS)); + diag_os_hrtus(maxres), diag_os_hrtus(resol / RESOL_ITERS)); if (diag_os_hrtus(maxres) >= 1200) { printf("WARNING : your system offers no clock >= 1kHz; this " "WILL be a problem!\n"); } - //test _getms() - resol=0; - maxres=0; - for (int i=0; i < RESOL_ITERS; i++) { + // test _getms() + resol = 0; + maxres = 0; + for (int i = 0; i < RESOL_ITERS; i++) { unsigned long tr; - t1=diag_os_getms(); - while ((t2=diag_os_getms()) == t1) {} - tr = (t2-t1); + t1 = diag_os_getms(); + while ((t2 = diag_os_getms()) == t1) { + } + tr = (t2 - t1); if (tr > maxres) { maxres = tr; } resol += tr; } - printf("diag_os_getms() resolution <= ~%llums, avg ~%llums\n", maxres, resol / RESOL_ITERS); - if (t2 > ((unsigned long)(-1) - 1000*30*60)) { - //unlikely, since 32-bit milliseconds will wrap in 49.7 days - printf("warning : diag_os_getms() will wrap in <30 minutes ! Consider rebooting...\n"); + printf("diag_os_getms() resolution <= ~%llums, avg ~%llums\n", maxres, + resol / RESOL_ITERS); + if (t2 > ((unsigned long)(-1) - 1000 * 30 * 60)) { + // unlikely, since 32-bit milliseconds will wrap in 49.7 days + printf("warning : diag_os_getms() will wrap in <30 minutes ! Consider " + "rebooting...\n"); } - //test _millisleep() VS _gethrt() + // test _millisleep() VS _gethrt() printf("testing diag_os_millisleep(), this will take a moment...\n"); - for (int testval=50; testval > 0; testval -= 2) { - //Start with the highest timeout + for (int testval = 50; testval > 0; testval -= 2) { + // Start with the highest timeout int i; const int iters = 5; - long long avgerr, max, min, tsum; //in us + long long avgerr, max, min, tsum; // in us - tsum=0; - max=0; - min=testval*1000; + tsum = 0; + max = 0; + min = testval * 1000; - for (i=0; i< iters; i++) { + for (i = 0; i < iters; i++) { long long timediff; - tl1=diag_os_gethrt(); + tl1 = diag_os_gethrt(); diag_os_millisleep(testval); - tl2=diag_os_gethrt(); - timediff= (long long) diag_os_hrtus(tl2 - tl1); + tl2 = diag_os_gethrt(); + timediff = (long long)diag_os_hrtus(tl2 - tl1); tsum += timediff; - //update extreme records if required: + // update extreme records if required: if (timediff < min) { min = timediff; } @@ -660,105 +683,110 @@ void diag_os_calibrate(void) { max = timediff; } } - avgerr= (tsum/iters) - (testval*1000); //average error in us - //a high spread (max-min) indicates initbus with dumb interfaces will be - //fragile. We just print it out; there's not much we can do to fix this. - if ((min < (testval*1000)) || (avgerr > 900)) { + avgerr = (tsum / iters) - (testval * 1000); // average error in us + // a high spread (max-min) indicates initbus with dumb interfaces will be + // fragile. We just print it out; there's not much we can do to fix this. + if ((min < (testval * 1000)) || (avgerr > 900)) { printf("diag_os_millisleep(%d) off by %lld%% (+%lldus)" - "; spread=%lld%%\n", testval, (avgerr*100/1000)/testval, avgerr, ((max-min)*100)/(testval*1000)); + "; spread=%lld%%\n", + testval, (avgerr * 100 / 1000) / testval, avgerr, + ((max - min) * 100) / (testval * 1000)); } if (testval >= 25) { testval -= 7; } - } //for testvals + } // for testvals - calibrate_done=1; + calibrate_done = 1; return; -} //diag_os_calibrate - +} // diag_os_calibrate -unsigned long diag_os_getms(void) { - //just use diag_os_gethrt() backend +unsigned long +diag_os_getms(void) { + // just use diag_os_gethrt() backend return diag_os_hrtus(diag_os_gethrt()) / 1000; } -//return high res timestamp, monotonic. -unsigned long long diag_os_gethrt(void) { +// return high res timestamp, monotonic. +unsigned long long +diag_os_gethrt(void) { assert(discover_done); -#if defined(_POSIX_TIMERS) && (SEL_HRT==S_POSIX || SEL_HRT==S_AUTO) - //units : ns +#if defined(_POSIX_TIMERS) && (SEL_HRT == S_POSIX || SEL_HRT == S_AUTO) + // units : ns struct timespec curtime = {0}; clock_gettime(clkid_gt, &curtime); - return curtime.tv_nsec + (curtime.tv_sec * 1000*1000*1000ULL); + return curtime.tv_nsec + (curtime.tv_sec * 1000 * 1000 * 1000ULL); #else - #warning Using gettimeofday() ! This is evil ! +# warning Using gettimeofday() ! This is evil ! -#ifndef HAVE_GETTIMEOFDAY - #error No implementation of gettimeofday() for your system! -#endif // HAVE_GETTIMEOFDAY +# ifndef HAVE_GETTIMEOFDAY +# error No implementation of gettimeofday() for your system! +# endif // HAVE_GETTIMEOFDAY - //Use gettimeofday anyway as a stopgap. This is evil - //because gettimeofday isn't guaranteed to be monotonic (always increasing) - //units : us + // Use gettimeofday anyway as a stopgap. This is evil + // because gettimeofday isn't guaranteed to be monotonic (always increasing) + // units : us struct timeval tv; unsigned long long rv; gettimeofday(&tv, NULL); - rv= tv.tv_usec + (tv.tv_sec * 1000000ULL); + rv = tv.tv_usec + (tv.tv_sec * 1000000ULL); return rv; #endif } -//convert a delta of diag_os_gethrt() timestamps to microseconds -//must match diag_os_gethrt() implementation! -unsigned long long diag_os_hrtus(unsigned long long hrdelta) { -#if defined(_POSIX_TIMERS) && (SEL_HRT==S_POSIX || SEL_HRT==S_AUTO) +// convert a delta of diag_os_gethrt() timestamps to microseconds +// must match diag_os_gethrt() implementation! +unsigned long long +diag_os_hrtus(unsigned long long hrdelta) { +#if defined(_POSIX_TIMERS) && (SEL_HRT == S_POSIX || SEL_HRT == S_AUTO) return hrdelta / 1000; #else return hrdelta; #endif // _POSIX_TIMERS } -diag_mtx *diag_os_newmtx(void) { - pthread_mutex_t *pmt; - diag_calloc(&pmt, 1); - if (pthread_mutex_init(pmt, NULL)) { - free(pmt); - return NULL; - } - return (diag_mtx *) pmt; +void +diag_os_initmtx(diag_mtx *mtx) { + pthread_mutex_init((pthread_mutex_t *)mtx, NULL); + return; } -void diag_os_delmtx(diag_mtx *mtx) { - pthread_mutex_t *pmt = (pthread_mutex_t *) mtx; - pthread_mutex_destroy(pmt); - free(pmt); +void +diag_os_initstaticmtx(UNUSED(diag_mtx *mtx)) { + // This should have been statically initialized (in the Pthreads case, + // specifically), so we do not do anything. return; } -void diag_os_lock(diag_mtx *mtx) { - pthread_mutex_t *pmt = (pthread_mutex_t *) mtx; - if (pthread_mutex_lock(pmt) == EDEADLK) { - //do we even check for error values... +void +diag_os_delmtx(diag_mtx *mtx) { + pthread_mutex_destroy((pthread_mutex_t *)mtx); + return; +} + +void +diag_os_lock(diag_mtx *mtx) { + if (pthread_mutex_lock((pthread_mutex_t *)mtx) == EDEADLK) { + // do we even check for error values... fprintf(stderr, "DEADLOCK !\n"); } return; } -bool diag_os_trylock(diag_mtx *mtx) { - pthread_mutex_t *pmt = (pthread_mutex_t *) mtx; - if (pthread_mutex_trylock(pmt)) { +bool +diag_os_trylock(diag_mtx *mtx) { + if (pthread_mutex_trylock((pthread_mutex_t *)mtx)) { return 0; } return 1; } -void diag_os_unlock(diag_mtx *mtx) { - pthread_mutex_t *pmt = (pthread_mutex_t *) mtx; - pthread_mutex_unlock(pmt); +void +diag_os_unlock(diag_mtx *mtx) { + pthread_mutex_unlock((pthread_mutex_t *)mtx); return; } - diff --git a/scantool/diag_os_unix.h b/scantool/diag_os_unix.h index f544a99e..60074887 100644 --- a/scantool/diag_os_unix.h +++ b/scantool/diag_os_unix.h @@ -30,8 +30,8 @@ extern "C" { #endif /****** OS-specific implementation selectors ******/ -/* These are for testing/debugging only, to force compilation of certain implementations - for diag_tty* and diag_os* functions. +/* These are for testing/debugging only, to force compilation of certain + implementations for diag_tty* and diag_os* functions. ### Map of features with more than one implementation related to POSIX ### @@ -57,38 +57,36 @@ extern "C" { a specific implementation using the #defines below. TODO: add compile tests to cmake? */ -#define S_AUTO 0 +#define S_AUTO 0 /* First set, for obviously OS-dependant features: */ -#define S_POSIX 1 -#define S_LINUX 2 +#define S_POSIX 1 +#define S_LINUX 2 #define S_OTHER 3 /* Second set, not necessarily OS-dependant */ -#define S_ALT1 1 -#define S_ALT2 2 +#define S_ALT1 1 +#define S_ALT2 2 /** Insert desired selectors here **/ -//example: +// example: //#define SEL_PERIODIC S_OTHER /* Default selectors: anything still undefined is set to S_AUTO which means "force nothing", i.e. "use most appropriate implementation". */ #ifndef SEL_PERIODIC -#define SEL_PERIODIC S_AUTO +# define SEL_PERIODIC S_AUTO #endif #ifndef SEL_SLEEP -#define SEL_SLEEP S_AUTO +# define SEL_SLEEP S_AUTO #endif #ifndef SEL_HRT -#define SEL_HRT S_AUTO +# define SEL_HRT S_AUTO #endif #ifndef SEL_SCHED -#define SEL_SCHED S_AUTO +# define SEL_SCHED S_AUTO #endif /****** ******/ - #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_OS_UNIX_H_ */ - diff --git a/scantool/diag_os_win.c b/scantool/diag_os_win.c index 707c5223..c61b16ac 100644 --- a/scantool/diag_os_win.c +++ b/scantool/diag_os_win.c @@ -8,13 +8,13 @@ * We run the process in high priority. * * WIN32 will use CreateTimerQueueTimer instead of the SIGALRM handler of unix. - * Right now there's no self-checking but it should be of OK accuracy for basic stuff ( keepalive messages ) + * Right now there's no self-checking but it should be of OK accuracy for basic stuff ( + keepalive messages ) * NOTE : that means at least WinXP is required. * additional timing info: http://www.windowstimestamp.com/description */ - #include #include #include @@ -28,20 +28,21 @@ #include "diag_l3.h" #include "diag_err.h" - #include #include -#include //for _kbhit, _getch -#include //for PRIu64 formatters - - -static int diag_os_init_done=0; +#include //for _kbhit, _getch +#include //for PRIu64 formatters -LARGE_INTEGER perfo_freq = {{0,0}}; //for use with QueryPerformanceFrequency and QueryPerformanceCounter -float pf_conv=0; //this will be (1E6 / perfo_freq) to convert counts to microseconds, i.e. [us]=[counts]*pf_conv -static int pfconv_valid=0; //flag after querying perfo_freq; nothing will not work without a performance counter -int shortsleep_reliable=0; //TODO : auto-detect this on startup. See diag_os_millisleep & diag_os_calibrate +static int diag_os_init_done = 0; +LARGE_INTEGER perfo_freq = {{0, 0}}; // for use with QueryPerformanceFrequency and + // QueryPerformanceCounter +float pf_conv = 0; // this will be (1E6 / perfo_freq) to convert counts to microseconds, + // i.e. [us]=[counts]*pf_conv +static int pfconv_valid = 0; // flag after querying perfo_freq; nothing will not work + // without a performance counter +int shortsleep_reliable = 0; // TODO : auto-detect this on startup. See diag_os_millisleep + // & diag_os_calibrate /* periodic callback: +* the current implementation uses non-async-signal-safe functions @@ -52,104 +53,113 @@ HANDLE hDiagTimer = INVALID_HANDLE_VALUE; CRITICAL_SECTION periodic_lock; -VOID CALLBACK timercallback(UNUSED(PVOID lpParam), BOOLEAN timedout) { +VOID CALLBACK +timercallback(UNUSED(PVOID lpParam), BOOLEAN timedout) { - if (!TryEnterCriticalSection(&periodic_lock)) return; + if (!TryEnterCriticalSection(&periodic_lock)) + return; if (!timedout) { - //this should never happen. - fprintf(stderr, FLFMT "Problem with OS timer callback! Report this !\n", FL); + // this should never happen. + fprintf(stderr, FLFMT "Problem with OS timer callback! Report this !\n", + FL); } else { - diag_l3_timer(); /* Call L3 Timer */ - diag_l2_timer(); /* Call L2 timer */ + diag_l3_timer(); /* Call L3 Timer */ + diag_l2_timer(); /* Call L2 timer */ } LeaveCriticalSection(&periodic_lock); return; } -//diag_os_init : a bit of a misnomer. This sets up a periodic callback -//to call diag_l3_timer and diag_l2_timer; that would sound like a job -//for "diag_os_sched". The WIN32 version of diag_os_init also -//calls diag_os_sched to increase thread priority. -//return 0 if ok +// diag_os_init : a bit of a misnomer. This sets up a periodic callback +// to call diag_l3_timer and diag_l2_timer; that would sound like a job +// for "diag_os_sched". The WIN32 version of diag_os_init also +// calls diag_os_sched to increase thread priority. +// return 0 if ok int diag_os_init(void) { - unsigned long tmo=ALARM_TIMEOUT; + unsigned long tmo = ALARM_TIMEOUT; if (diag_os_init_done) return 0; - diag_os_sched(); //call os_sched to increase thread priority. + diag_os_sched(); // call os_sched to increase thread priority. - //probably the nearest equivalent to a unix interval timer + associated alarm handler - //is the timer queue... so that's what we do. - //we create the timer in the default timerqueue + // probably the nearest equivalent to a unix interval timer + associated alarm + // handler is the timer queue... so that's what we do. we create the timer in the + // default timerqueue InitializeCriticalSection(&periodic_lock); - if (! CreateTimerQueueTimer(&hDiagTimer, NULL, - (WAITORTIMERCALLBACK) timercallback, NULL, tmo, tmo, - WT_EXECUTEDEFAULT)) { + if (!CreateTimerQueueTimer(&hDiagTimer, NULL, (WAITORTIMERCALLBACK)timercallback, + NULL, tmo, tmo, WT_EXECUTEDEFAULT)) { fprintf(stderr, FLFMT "CTQT error.\n", FL); hDiagTimer = INVALID_HANDLE_VALUE; return diag_iseterr(DIAG_ERR_GENERAL); } - //and get the current performance counter frequency. - //From MSDN docs : The frequency of the performance counter is fixed at system boot - // and is consistent across all processors. Therefore, the frequency - // need only be queried upon application initialization, and the result can be cached. + // and get the current performance counter frequency. + // From MSDN docs : The frequency of the performance counter is fixed at system + // boot and is consistent across all + // processors. + // Therefore, the frequency need only + // be queried upon application initialization, and the result can be cached. // - // Under what circumstances does QueryPerformanceFrequency return FALSE, - // or QueryPerformanceCounter return zero? - // ->This won't occur on any system that runs Windows XP or later. + // Under what circumstances does + // QueryPerformanceFrequency return FALSE, or + // QueryPerformanceCounter return zero? + // ->This won't occur on any system + // that runs Windows XP or later. - if ( !QueryPerformanceFrequency(&perfo_freq) || (perfo_freq.QuadPart==0)) { + if (!QueryPerformanceFrequency(&perfo_freq) || (perfo_freq.QuadPart == 0)) { fprintf(stderr, FLFMT "Fatal: could not QPF. Please report this !\n", FL); diag_os_close(); return diag_iseterr(DIAG_ERR_GENERAL); } - if (perfo_freq.QuadPart ==0) { - fprintf(stderr, FLFMT "Fatal: QPF reports 0Hz. Please report this !\n", FL); + if (perfo_freq.QuadPart == 0) { + fprintf(stderr, FLFMT "Fatal: QPF reports 0Hz. Please report this !\n", + FL); diag_os_close(); return diag_iseterr(DIAG_ERR_GENERAL); } - pf_conv=1.0E6 / perfo_freq.QuadPart; - pfconv_valid =1; + pf_conv = 1.0E6 / perfo_freq.QuadPart; + pfconv_valid = 1; - if (diag_l0_debug & DIAG_DEBUG_TIMER) { - fprintf(stderr, FLFMT "Performance counter frequency : %9"PRIu64"Hz\n", FL, perfo_freq.QuadPart); + if (diag_l0_debug_load() & DIAG_DEBUG_TIMER) { + fprintf(stderr, FLFMT "Performance counter frequency : %9" PRIu64 "Hz\n", + FL, perfo_freq.QuadPart); } diag_os_calibrate(); diag_os_init_done = 1; return 0; -} //diag_os_init +} // diag_os_init -//diag_os_close: delete alarm handlers / periodic timers -//return 0 if ok -int diag_os_close() { +// diag_os_close: delete alarm handlers / periodic timers +// return 0 if ok +int +diag_os_close() { DWORD err; - diag_os_init_done=0; //diag_os_init will have to be done again past this point. + diag_os_init_done = 0; // diag_os_init will have to be done again past this point. if (hDiagTimer != INVALID_HANDLE_VALUE) { - if (DeleteTimerQueueTimer(NULL,hDiagTimer,NULL)) { - //success + if (DeleteTimerQueueTimer(NULL, hDiagTimer, NULL)) { + // success goto goodexit; } - //From MSDN : if error_io_pending, not necessary to call again. - err=GetLastError(); - if (err==ERROR_IO_PENDING) { - //This is OK and the queue will be deleted automagically. - //No need to pester the user about this + // From MSDN : if error_io_pending, not necessary to call again. + err = GetLastError(); + if (err == ERROR_IO_PENDING) { + // This is OK and the queue will be deleted automagically. + // No need to pester the user about this goto goodexit; } - //Otherwise, try again + // Otherwise, try again fprintf(stderr, FLFMT "Could not DTQT. Retrying...", FL); - Sleep(500); //should be more than enough for IO to complete... - if (DeleteTimerQueueTimer(NULL,hDiagTimer,NULL)) { + Sleep(500); // should be more than enough for IO to complete... + if (DeleteTimerQueueTimer(NULL, hDiagTimer, NULL)) { fprintf(stderr, "OK !\n"); goto goodexit; } @@ -160,273 +170,291 @@ int diag_os_close() { hDiagTimer = INVALID_HANDLE_VALUE; DeleteCriticalSection(&periodic_lock); return 0; -} //diag_os_close - +} // diag_os_close // void diag_os_millisleep(unsigned int ms) { - //This version self-corrects if Sleep() overshoots; - //if it undershoots then we run an empty loop for the remaining - //time. Eventually "correction" should contain the biggest - //overshoot so far; this means every subsequent calls - //will almost always run through the NOP loop. + // This version self-corrects if Sleep() overshoots; + // if it undershoots then we run an empty loop for the remaining + // time. Eventually "correction" should contain the biggest + // overshoot so far; this means every subsequent calls + // will almost always run through the NOP loop. LARGE_INTEGER qpc1, qpc2; long real_t; - static long correction=0; //auto-adjusment (in us) - LONGLONG tdiff; //measured (elapsed) time (in counts) + static long correction = 0; // auto-adjusment (in us) + LONGLONG tdiff; // measured (elapsed) time (in counts) QueryPerformanceCounter(&qpc1); assert(pfconv_valid); - tdiff=0; + tdiff = 0; - if (perfo_freq.QuadPart ==0) { + if (perfo_freq.QuadPart == 0) { Sleep(ms); return; } - LONGLONG reqt= (ms * perfo_freq.QuadPart)/1000; //required # of counts + LONGLONG reqt = (ms * perfo_freq.QuadPart) / 1000; // required # of counts - if ( shortsleep_reliable || (((long) ms-(correction/1000)) > 5)) { - //if reliable, or long sleep : try - Sleep(ms - (correction/1000)); + if (shortsleep_reliable || (((long)ms - (correction / 1000)) > 5)) { + // if reliable, or long sleep : try + Sleep(ms - (correction / 1000)); QueryPerformanceCounter(&qpc2); - tdiff= qpc2.QuadPart - qpc1.QuadPart; + tdiff = qpc2.QuadPart - qpc1.QuadPart; if (tdiff > reqt) { - //we busted the required time by: - real_t = (long) (pf_conv * (tdiff-reqt)); //in us + // we busted the required time by: + real_t = (long)(pf_conv * (tdiff - reqt)); // in us if (real_t > 1000) { correction += real_t; - if (correction > 4000) correction = 4000; + if (correction > 4000) + correction = 4000; } return; } } - //do NOP loop for short sleeps for the remainder. This is ugly - //but could help on some systems - //if Sleep(ms) was too short this will bring us near - //the requested value. + // do NOP loop for short sleeps for the remainder. This is ugly + // but could help on some systems + // if Sleep(ms) was too short this will bring us near + // the requested value. while (tdiff < reqt) { QueryPerformanceCounter(&qpc2); - tdiff= qpc2.QuadPart - qpc1.QuadPart; + tdiff = qpc2.QuadPart - qpc1.QuadPart; } return; -} //diag_os_millisleep - +} // diag_os_millisleep int diag_os_ipending(void) { if (_kbhit()) { - (void) _getch(); + (void)_getch(); return 1; } return 0; } -//diag_os_sched : set high priority for this thread/process. -//this is called from most diag_l0_* devices; calling more than once -//will harm nothing. There is no "opposite" function of this, to -//reset normal priority. -//we ifdef the body of the function according to the OS capabilities +// diag_os_sched : set high priority for this thread/process. +// this is called from most diag_l0_* devices; calling more than once +// will harm nothing. There is no "opposite" function of this, to +// reset normal priority. +// we ifdef the body of the function according to the OS capabilities int diag_os_sched(void) { - static int os_sched_done=0; - int rv=0; + static int os_sched_done = 0; + int rv = 0; if (os_sched_done) - return 0; //don't do it more than once + return 0; // don't do it more than once HANDLE curprocess, curthread; - //set the current process to high priority. - //the resultant "base priority" is a combination of process priority and thread priority. - curprocess=GetCurrentProcess(); - curthread=GetCurrentThread(); - if (! SetPriorityClass(curprocess, HIGH_PRIORITY_CLASS)) { - fprintf(stderr, FLFMT "Warning: could not increase process priority. Timing may be impaired.\n", FL); + // set the current process to high priority. + // the resultant "base priority" is a combination of process priority and thread + // priority. + curprocess = GetCurrentProcess(); + curthread = GetCurrentThread(); + if (!SetPriorityClass(curprocess, HIGH_PRIORITY_CLASS)) { + fprintf(stderr, + FLFMT + "Warning: could not increase process priority. Timing may be " + "impaired.\n", + FL); } - if (! SetThreadPriority(curthread, THREAD_PRIORITY_HIGHEST)) { - fprintf(stderr, FLFMT "Warning : could not increase thread priority. Timing may be impaired.\n", FL); + if (!SetThreadPriority(curthread, THREAD_PRIORITY_HIGHEST)) { + fprintf(stderr, + FLFMT + "Warning : could not increase thread priority. Timing may be " + "impaired.\n", + FL); } - rv=0; + rv = 0; - os_sched_done=1; + os_sched_done = 1; return rv; -} //of diag_os_sched - - +} // of diag_os_sched -//diag_os_geterr : get OS-specific error string. -//Either gets the last error if os_errno==0, or print the -//message associated with the specified os_errno +// diag_os_geterr : get OS-specific error string. +// Either gets the last error if os_errno==0, or print the +// message associated with the specified os_errno // XXX this is not async-safe / re-entrant ! // -const char *diag_os_geterr(OS_ERRTYPE os_errno) { - //to make this re-entrant, we would need CreateMutex OpenMutex etc. - static char errbuf[160]=""; +const char * +diag_os_geterr(OS_ERRTYPE os_errno) { + // to make this re-entrant, we would need CreateMutex OpenMutex etc. + static char errbuf[160] = ""; LPVOID errstr; if (os_errno == 0) - os_errno=GetLastError(); - - if (os_errno !=0 ) { - DWORD elen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - os_errno, - 0, - (LPTSTR) &errstr, - 0, - NULL); + os_errno = GetLastError(); + + if (os_errno != 0) { + DWORD elen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, os_errno, 0, (LPTSTR)&errstr, 0, NULL); if (elen) { - snprintf(errbuf, sizeof(errbuf), "%s", (const char *) errstr); + snprintf(errbuf, sizeof(errbuf), "%s", (const char *)errstr); LocalFree(errstr); } else { - //formatmessage failed... - snprintf(errbuf, sizeof(errbuf), "UNK:%u", (unsigned int) os_errno); + // formatmessage failed... + snprintf(errbuf, sizeof(errbuf), "UNK:%u", (unsigned int)os_errno); } } else { strcpy(errbuf, "No error"); } - return (const char *) errbuf; - + return (const char *)errbuf; } -//diag_os_calibrate : run some timing tests to make sure we have -//adequate performances. -//On win32, running diag_os_millisleep repeatedly allows it to -//auto-adjust to a certain degree. +// diag_os_calibrate : run some timing tests to make sure we have +// adequate performances. +// On win32, running diag_os_millisleep repeatedly allows it to +// auto-adjust to a certain degree. -void diag_os_calibrate(void) { - static int calibrate_done=0; //do it only once - int testval; //timeout to test +void +diag_os_calibrate(void) { + static int calibrate_done = 0; // do it only once + int testval; // timeout to test LARGE_INTEGER qpc1, qpc2; LONGLONG tsum; - #define RESOL_ITERS 10 - unsigned long long resol, maxres, tl1, tl2; //all for _gethrt() test - unsigned long t1, t2; //for _getms() test +#define RESOL_ITERS 10 + unsigned long long resol, maxres, tl1, tl2; // all for _gethrt() test + unsigned long t1, t2; // for _getms() test assert(pfconv_valid); if (calibrate_done) return; - //test _gethrt() - resol=0; - maxres=0; - for (int i=0; i < RESOL_ITERS; i++) { + // test _gethrt() + resol = 0; + maxres = 0; + for (int i = 0; i < RESOL_ITERS; i++) { unsigned long long tr; - tl1=diag_os_gethrt(); - while ((tl2=diag_os_gethrt()) == tl1) {} - tr = (tl2-tl1); - if (tr > maxres) maxres = tr; + tl1 = diag_os_gethrt(); + while ((tl2 = diag_os_gethrt()) == tl1) { + } + tr = (tl2 - tl1); + if (tr > maxres) + maxres = tr; resol += tr; } printf("diag_os_gethrt() resolution <= %luus, avg ~%luus\n", - (unsigned long) diag_os_hrtus(maxres), (unsigned long) diag_os_hrtus(resol / RESOL_ITERS)); + (unsigned long)diag_os_hrtus(maxres), + (unsigned long)diag_os_hrtus(resol / RESOL_ITERS)); - //now test diag_os_getms - t1=diag_os_getms(); - while ( ((t2=diag_os_getms())-t1) ==0) {} - printf("diag_os_getms() resolution: ~%lums.\n", t2-t1); + // now test diag_os_getms + t1 = diag_os_getms(); + while (((t2 = diag_os_getms()) - t1) == 0) { + } + printf("diag_os_getms() resolution: ~%lums.\n", t2 - t1); printf("Calibrating timing, this will take a few seconds...\n"); - for (testval=50; testval > 0; testval -= 2) { - //Start with the highest timeout to force _millisleep to use Sleep() - //and therefore start auto-correcting right away. + for (testval = 50; testval > 0; testval -= 2) { + // Start with the highest timeout to force _millisleep to use Sleep() + // and therefore start auto-correcting right away. int i; LONGLONG counts, avgerr, max, min; - max=0; + max = 0; - tsum=0; - counts=(testval*perfo_freq.QuadPart)/1000; //expected # of counts - min=counts; + tsum = 0; + counts = (testval * perfo_freq.QuadPart) / 1000; // expected # of counts + min = counts; #define CAL_ITERS 6 - for (i=0; i< CAL_ITERS; i++) { + for (i = 0; i < CAL_ITERS; i++) { LONGLONG timediff; QueryPerformanceCounter(&qpc1); diag_os_millisleep(testval); QueryPerformanceCounter(&qpc2); - timediff=(qpc2.QuadPart-qpc1.QuadPart); + timediff = (qpc2.QuadPart - qpc1.QuadPart); tsum += timediff; - //update extreme records if required: + // update extreme records if required: if (timediff < min) min = timediff; if (timediff > max) max = timediff; } - avgerr= (LONGLONG) (((tsum/CAL_ITERS)-counts) * pf_conv); //average error in us - //a high spread (max-min) indicates initbus with dumb interfaces will be - //fragile. We just print it out; there's not much we can do to fix this. + avgerr = (LONGLONG)(((tsum / CAL_ITERS) - counts) * pf_conv); // average + // error in + // us + // a high spread (max-min) indicates initbus with dumb interfaces will be + // fragile. We just print it out; there's not much we can do to fix this. if ((min < counts) || (avgerr > 900)) - printf("diag_os_millisleep(%d) off by %+"PRId64"%% (%+"PRId64"us)" - "; spread=%"PRIu64"%%\n", testval, (avgerr*100/1000)/testval, avgerr, ((max-min)*100)/counts); + printf("diag_os_millisleep(%d) off by %+" PRId64 "%% (%+" PRId64 + "us)" + "; spread=%" PRIu64 "%%\n", + testval, (avgerr * 100 / 1000) / testval, avgerr, + ((max - min) * 100) / counts); - - if (testval>=30) + if (testval >= 30) testval -= 8; - } //for testvals + } // for testvals printf("Calibration done.\n"); - calibrate_done=1; + calibrate_done = 1; return; -} //diag_os_calibrate +} // diag_os_calibrate -//return monotonic clock time, ms precision. -//resolution and accuracy are not important; GetTickCount() is good enough -unsigned long diag_os_getms(void) { - return (unsigned long) GetTickCount(); +// return monotonic clock time, ms precision. +// resolution and accuracy are not important; GetTickCount() is good enough +unsigned long +diag_os_getms(void) { + return (unsigned long)GetTickCount(); } -//get high resolution timestamp -unsigned long long diag_os_gethrt(void) { +// get high resolution timestamp +unsigned long long +diag_os_gethrt(void) { LARGE_INTEGER qpc1; assert(pfconv_valid); QueryPerformanceCounter(&qpc1); - return (unsigned long long) qpc1.QuadPart; + return (unsigned long long)qpc1.QuadPart; } -//convert a delta of diag_os_gethrt() timestamps to microseconds -unsigned long long diag_os_hrtus(unsigned long long hrdelta) { +// convert a delta of diag_os_gethrt() timestamps to microseconds +unsigned long long +diag_os_hrtus(unsigned long long hrdelta) { assert(pfconv_valid); - return (unsigned long long) (hrdelta * (double) pf_conv); + return (unsigned long long)(hrdelta * (double)pf_conv); } +void +diag_os_initmtx(diag_mtx *mtx) { + InitializeCriticalSection((CRITICAL_SECTION *)mtx); + return; +} -diag_mtx *diag_os_newmtx(void) { - CRITICAL_SECTION *lpc; - diag_calloc(&lpc, 1); - InitializeCriticalSection(lpc); - return (diag_mtx *) lpc; +void +diag_os_initstaticmtx(diag_mtx *mtx) { + // No static initialization of mutexes on Windows. + diag_os_initmtx(mtx); + return; } -void diag_os_delmtx(diag_mtx *mtx) { - CRITICAL_SECTION *lpc = (CRITICAL_SECTION *) mtx; - DeleteCriticalSection(lpc); - free(lpc); +void +diag_os_delmtx(diag_mtx *mtx) { + DeleteCriticalSection((CRITICAL_SECTION *)mtx); return; } -void diag_os_lock(diag_mtx *mtx) { - CRITICAL_SECTION *lpc = (CRITICAL_SECTION *) mtx; - EnterCriticalSection(lpc); +void +diag_os_lock(diag_mtx *mtx) { + EnterCriticalSection((CRITICAL_SECTION *)mtx); return; } -bool diag_os_trylock(diag_mtx *mtx) { - CRITICAL_SECTION *lpc = (CRITICAL_SECTION *) mtx; - if (!TryEnterCriticalSection(lpc)) return 0; +bool +diag_os_trylock(diag_mtx *mtx) { + if (!TryEnterCriticalSection((CRITICAL_SECTION *)mtx)) + return 0; return 1; } -void diag_os_unlock(diag_mtx *mtx) { - CRITICAL_SECTION *lpc = (CRITICAL_SECTION *) mtx; - LeaveCriticalSection(lpc); +void +diag_os_unlock(diag_mtx *mtx) { + LeaveCriticalSection((CRITICAL_SECTION *)mtx); return; } - diff --git a/scantool/diag_test.c b/scantool/diag_test.c index ed546703..370ce927 100644 --- a/scantool/diag_test.c +++ b/scantool/diag_test.c @@ -44,12 +44,11 @@ struct test_item { bool test_dupmsg(void); bool test_periodic(void); -static struct test_item test_list[] = { - {"msg duplication", test_dupmsg}, - {"periodic timers", test_periodic} -}; +static struct test_item test_list[] = {{"msg duplication", test_dupmsg}, + {"periodic timers", test_periodic}}; -bool test_dupmsg(void) { +bool +test_dupmsg(void) { struct diag_msg *msg0, *msg1, *msg2; struct diag_msg *newchain; @@ -69,11 +68,10 @@ bool test_dupmsg(void) { newchain = diag_dupmsg(msg0); - if ((newchain->rxtime != 0) || - (newchain->next->rxtime != 1) || - (newchain->next->next->rxtime != 2)) { - printf("chain data / order mismatch\n"); - return 0; + if ((newchain->rxtime != 0) || (newchain->next->rxtime != 1) || + (newchain->next->next->rxtime != 2)) { + printf("chain data / order mismatch\n"); + return 0; } diag_freemsg(msg0); diag_freemsg(newchain); @@ -81,80 +79,87 @@ bool test_dupmsg(void) { } /********** construct a dummy L0 driver */ -int d0_init(void) { +int +d0_init(void) { return 0; } -int d0_new(struct diag_l0_device *dl0d) { - (void) dl0d; +int +d0_new(struct diag_l0_device *dl0d) { + (void)dl0d; return 0; } -struct cfgi *d0_getcfg(struct diag_l0_device *dl0d) { - (void) dl0d; +struct cfgi * +d0_getcfg(struct diag_l0_device *dl0d) { + (void)dl0d; return NULL; } -void d0_del(struct diag_l0_device *dl0d) { - (void) dl0d; +void +d0_del(struct diag_l0_device *dl0d) { + (void)dl0d; } -int d0_open(struct diag_l0_device *dl0d, int l1_proto) { - (void) dl0d; - (void) l1_proto; +int +d0_open(struct diag_l0_device *dl0d, int l1_proto) { + (void)dl0d; + (void)l1_proto; return 0; } -void d0_close(struct diag_l0_device *dl0d) { - (void) dl0d; +void +d0_close(struct diag_l0_device *dl0d) { + (void)dl0d; } -uint32_t d0_getflags(struct diag_l0_device *dl0d) { - (void) dl0d; +uint32_t +d0_getflags(struct diag_l0_device *dl0d) { + (void)dl0d; return 0; } -int d0_recv(struct diag_l0_device *dl0d, - const char *subinterface, void *data, size_t len, unsigned int timeout) { - (void) dl0d; - (void) subinterface; - (void) data; - (void) len; - (void) timeout; +int +d0_recv(struct diag_l0_device *dl0d, const char *subinterface, void *data, size_t len, + unsigned int timeout) { + (void)dl0d; + (void)subinterface; + (void)data; + (void)len; + (void)timeout; return 0; } -int d0_send(struct diag_l0_device *dl0d, - const char *subinterface, const void *data, size_t len) { - (void) dl0d; - (void) subinterface; - (void) data; - (void) len; +int +d0_send(struct diag_l0_device *dl0d, const char *subinterface, const void *data, + size_t len) { + (void)dl0d; + (void)subinterface; + (void)data; + (void)len; return 0; } -int d0_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { - (void) dl0d; - (void) cmd; - (void) data; +int +d0_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) { + (void)dl0d; + (void)cmd; + (void)data; return 0; } -static struct diag_l0 dummy_dl0 = { - .longname = "dummy L0", - .shortname = "dummy L0", - .l1proto_mask = -1, //support everything - .init = d0_init, - ._new = d0_new, - ._getcfg = d0_getcfg, - ._del = d0_del, - ._open = d0_open, - ._close = d0_close, - ._getflags = d0_getflags, - ._recv = d0_recv, - ._send = d0_send, - ._ioctl = d0_ioctl -}; - -#define TEST_PERIODIC_DURATION 800 //in ms +static struct diag_l0 dummy_dl0 = {.longname = "dummy L0", + .shortname = "dummy L0", + .l1proto_mask = -1, // support everything + .init = d0_init, + ._new = d0_new, + ._getcfg = d0_getcfg, + ._del = d0_del, + ._open = d0_open, + ._close = d0_close, + ._getflags = d0_getflags, + ._recv = d0_recv, + ._send = d0_send, + ._ioctl = d0_ioctl}; + +#define TEST_PERIODIC_DURATION 800 // in ms /** periodic callback test * Start an L2, let the periodic timer run a few times, then stop */ -bool test_periodic(void) { - struct diag_l0_device dl0d = { - .dl0 = &dummy_dl0 - }; +bool +test_periodic(void) { + struct diag_l0_device dl0d = {.dl0 = &dummy_dl0}; struct diag_l2_conn *dl2c; unsigned long ts; @@ -163,7 +168,7 @@ bool test_periodic(void) { return 0; } - ts = diag_os_getms() + TEST_PERIODIC_DURATION; //anticipated endtime + ts = diag_os_getms() + TEST_PERIODIC_DURATION; // anticipated endtime dl2c = diag_l2_StartCommunications(&dl0d, DIAG_L2_PROT_TEST, 0, 0, 0, 0); if (dl2c == NULL) { @@ -171,8 +176,9 @@ bool test_periodic(void) { diag_l2_close(&dl0d); return 0; } - dl2c->tinterval = 0; //force timer expiry on every timer callback - while (diag_os_getms() < ts) {} + dl2c->tinterval = 0; // force timer expiry on every timer callback + while (diag_os_getms() < ts) { + } diag_l2_StopCommunications(dl2c); diag_l2_close(&dl0d); @@ -180,11 +186,12 @@ bool test_periodic(void) { } /** ret 1 if success */ -static bool run_tests(void) { +static bool +run_tests(void) { bool rv = 1; unsigned i; - for (i=0; i < ARRAY_SIZE(test_list); i++) { + for (i = 0; i < ARRAY_SIZE(test_list); i++) { printf("Testing %s:\t", test_list[i].name); if (!test_list[i].testfunc()) { rv = 0; @@ -197,12 +204,11 @@ static bool run_tests(void) { return rv; } - int -main(int argc, char **argv) { +main(int argc, char **argv) { bool rv; - (void) argc; - (void) argv; + (void)argc; + (void)argv; if (diag_init()) { printf("error in initialization\n"); @@ -211,8 +217,9 @@ main(int argc, char **argv) { rv = run_tests(); - (void) diag_end(); + (void)diag_end(); - if (!rv) return -1; + if (!rv) + return -1; return 0; } diff --git a/scantool/diag_tty.h b/scantool/diag_tty.h index f941c72d..5daf5f50 100644 --- a/scantool/diag_tty.h +++ b/scantool/diag_tty.h @@ -7,21 +7,22 @@ * support arbitrary speeds for some L0 links. */ - #include "diag.h" -#include "diag_l0.h" //needed for diag_l0_debug +#include "diag_l0.h" //needed for diag_l0_debug -#define IFLUSH_TIMEOUT 30 //timeout to use when calling diag_tty_read from diag_tty_iflush to purge RX buffer. - //must not be too long or diag_l0_dumb:slowinit() will not work -#define MAXTIMEOUT 10000 //ms; for diag_tty_read() +#define IFLUSH_TIMEOUT \ + 30 // timeout to use when calling diag_tty_read from diag_tty_iflush to purge RX + // buffer. +// must not be too long or diag_l0_dumb:slowinit() will not work +#define MAXTIMEOUT 10000 // ms; for diag_tty_read() /* * Parity settings */ enum diag_parity { - diag_par_e = 1, /* Even parity */ - diag_par_o = 2, /* Odd parity */ - diag_par_n = 3 /* No parity */ + diag_par_e = 1, /* Even parity */ + diag_par_o = 2, /* Odd parity */ + diag_par_n = 3 /* No parity */ }; enum diag_databits { @@ -31,21 +32,17 @@ enum diag_databits { diag_databits_5 = 5 }; -enum diag_stopbits { - diag_stopbits_1 = 1, - diag_stopbits_2 = 2 -}; +enum diag_stopbits { diag_stopbits_1 = 1, diag_stopbits_2 = 2 }; struct diag_serial_settings { - unsigned int speed; //in bps of course + unsigned int speed; // in bps of course enum diag_databits databits; enum diag_stopbits stopbits; enum diag_parity parflag; }; - /*** Public functions ***/ -typedef void ttyp; //used as "(tty_internal_struct *) ttyp" in tty code +typedef void ttyp; // used as "(tty_internal_struct *) ttyp" in tty code /** Get available serial ports * @@ -72,8 +69,7 @@ void diag_tty_close(ttyp *tty_int); * * @return 0 if ok. */ -int diag_tty_setup(ttyp *tty_int, - const struct diag_serial_settings *pss); +int diag_tty_setup(ttyp *tty_int, const struct diag_serial_settings *pss); /** Set DTR and RTS lines. * @@ -83,7 +79,6 @@ int diag_tty_setup(ttyp *tty_int, */ int diag_tty_control(ttyp *tty_int, unsigned int dtr, unsigned int rts); - /** Flush pending input. * * This probably always takes IFLUSH_TIMEOUT to complete since it calls diag_tty_read. @@ -98,21 +93,19 @@ int diag_tty_iflush(ttyp *tty_int); // c) if there was a real error, return diag_iseterr(x) // d) never return 0 // TODO : clarify if calling with timeout==0 is useful (probably not, nobody does). -ssize_t diag_tty_read(ttyp *tty_int, - void *buf, size_t count, unsigned int timeout); +ssize_t diag_tty_read(ttyp *tty_int, void *buf, size_t count, unsigned int timeout); /** Write bytes to tty (blocking). * - * @param count: Attempt to write [count] bytes, block (== do not return) until write has completed. + * @param count: Attempt to write [count] bytes, block (== do not return) until write + *has completed. * @return # of bytes written; \<0 if error. * @note It is unclear whether the different OS mechanisms to flush write buffers actually * guarantee that serial data has physically sent, * or only that the data was flushed as far "downstream" as possible, for example * to a UART / device driver buffer. */ -ssize_t diag_tty_write(ttyp *tty_int, - const void *buf, const size_t count); - +ssize_t diag_tty_write(ttyp *tty_int, const void *buf, const size_t count); /** Send a break on TXD. * @param ms: duration (milliseconds) @@ -129,5 +122,4 @@ int diag_tty_break(ttyp *tty_int, const unsigned int ms); */ int diag_tty_fastbreak(ttyp *tty_int, const unsigned int ms); - #endif /* _DIAG_TTY_H_ */ diff --git a/scantool/diag_tty_unix.c b/scantool/diag_tty_unix.c index e15b30cd..c88f7656 100644 --- a/scantool/diag_tty_unix.c +++ b/scantool/diag_tty_unix.c @@ -43,8 +43,10 @@ #include "diag_err.h" #include "diag_tty_unix.h" -#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT==S_POSIX || SEL_TIMEOUT==S_AUTO) -#define PT_REPEAT 1000 //after the nominal timeout period the timer will expire every PT_REPEAT us. +#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT == S_POSIX || SEL_TIMEOUT == S_AUTO) +# define PT_REPEAT \ + 1000 // after the nominal timeout period the timer will expire every + // PT_REPEAT us. static void diag_tty_rw_timeout_handler(UNUSED(int sig), siginfo_t *si, UNUSED(void *uc)) { assert(si->si_value.sival_ptr != NULL); @@ -53,10 +55,11 @@ diag_tty_rw_timeout_handler(UNUSED(int sig), siginfo_t *si, UNUSED(void *uc)) { } #endif -ttyp *diag_tty_open(const char *portname) { +ttyp * +diag_tty_open(const char *portname) { int rv; struct unix_tty_int *uti; -#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT==S_POSIX || SEL_TIMEOUT==S_AUTO) +#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT == S_POSIX || SEL_TIMEOUT == S_AUTO) struct sigevent to_sigev; struct sigaction sa; clockid_t timeout_clkid; @@ -64,23 +67,26 @@ ttyp *diag_tty_open(const char *portname) { assert(portname); - rv = diag_calloc(&uti,1); + rv = diag_calloc(&uti, 1); if (rv != 0) { return diag_pseterr(rv); } -#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT==S_POSIX || SEL_TIMEOUT==S_AUTO) - //set-up the r/w timeouts clock - here we just create it; it will be armed when needed - #ifdef _POSIX_MONOTONIC_CLOCK +#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT == S_POSIX || SEL_TIMEOUT == S_AUTO) + // set-up the r/w timeouts clock - here we just create it; it will be armed when + // needed +# ifdef _POSIX_MONOTONIC_CLOCK timeout_clkid = CLOCK_MONOTONIC; - #else +# else timeout_clkid = CLOCK_REALTIME; - #endif // _POSIX_MONOTONIC_CLOCK +# endif // _POSIX_MONOTONIC_CLOCK sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = diag_tty_rw_timeout_handler; sigemptyset(&sa.sa_mask); if (sigaction(SIGUSR1, &sa, NULL) != 0) { - fprintf(stderr, FLFMT "Could not set-up action for timeout timer... report this\n", FL); + fprintf(stderr, + FLFMT "Could not set-up action for timeout timer... report this\n", + FL); free(uti); return diag_pseterr(DIAG_ERR_GENERAL); } @@ -89,7 +95,8 @@ ttyp *diag_tty_open(const char *portname) { to_sigev.sigev_signo = SIGUSR1; to_sigev.sigev_value.sival_ptr = uti; if (timer_create(timeout_clkid, &to_sigev, &uti->timerid) != 0) { - fprintf(stderr, FLFMT "Could not create timeout timer... report this\n", FL); + fprintf(stderr, FLFMT "Could not create timeout timer... report this\n", + FL); free(uti); return diag_pseterr(DIAG_ERR_GENERAL); } @@ -99,17 +106,17 @@ ttyp *diag_tty_open(const char *portname) { size_t n = strlen(portname) + 1; - if ((rv=diag_malloc(&uti->name, n))) { + if ((rv = diag_malloc(&uti->name, n))) { free(uti); return diag_pseterr(rv); } strncpy(uti->name, portname, n); - //past this point, we can call diag_tty_close(uti) to abort in case of errors + // past this point, we can call diag_tty_close(uti) to abort in case of errors errno = 0; -#if defined(O_NONBLOCK) && (SEL_TTYOPEN==S_ALT1 || SEL_TTYOPEN==S_AUTO) +#if defined(O_NONBLOCK) && (SEL_TTYOPEN == S_ALT1 || SEL_TTYOPEN == S_AUTO) /* * For POSIX behavior: Open serial device non-blocking to avoid * modem control issues, then set to blocking. @@ -139,21 +146,22 @@ ttyp *diag_tty_open(const char *portname) { } } #else - #ifndef O_NONBLOCK - #warning No O_NONBLOCK on your system ?! Please report this - #endif +# ifndef O_NONBLOCK +# warning No O_NONBLOCK on your system ?! Please report this +# endif uti->fd = open(uti->name, O_RDWR); #endif // O_NONBLOCK if (uti->fd >= 0) { - if (diag_l0_debug & DIAG_DEBUG_OPEN) { - fprintf(stderr, FLFMT "Device %s opened, fd %d\n", FL, - uti->name, uti->fd); + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) { + fprintf(stderr, FLFMT "Device %s opened, fd %d\n", FL, uti->name, + uti->fd); } } else { fprintf(stderr, - FLFMT "Could not open \"%s\" : %s. " + FLFMT + "Could not open \"%s\" : %s. " "Make sure the device specified corresponds to the " "serial device your interface is connected to.\n", FL, uti->name, strerror(errno)); @@ -169,8 +177,8 @@ ttyp *diag_tty_open(const char *portname) { #if defined(__linux__) if (ioctl(uti->fd, TIOCGSERIAL, &uti->ss_orig) < 0) { - fprintf(stderr, - FLFMT "open: TIOCGSERIAL failed: %s\n", FL, strerror(errno)); + fprintf(stderr, FLFMT "open: TIOCGSERIAL failed: %s\n", FL, + strerror(errno)); uti->tioc_works = 0; } else { uti->ss_cur = uti->ss_orig; @@ -179,37 +187,35 @@ ttyp *diag_tty_open(const char *portname) { #endif if (ioctl(uti->fd, TIOCMGET, &uti->modemflags) < 0) { - fprintf(stderr, - FLFMT "open: TIOCMGET failed: %s\n", FL, strerror(errno)); + fprintf(stderr, FLFMT "open: TIOCMGET failed: %s\n", FL, strerror(errno)); diag_tty_close(uti); return diag_pseterr(DIAG_ERR_GENERAL); } -#ifdef USE_TERMIOS2 +#ifdef USE_TERMIOS2 rv = ioctl(uti->fd, TCGETS, &uti->st_orig); #else rv = tcgetattr(uti->fd, &uti->st_orig); #endif if (rv != 0) { - fprintf(stderr, FLFMT "open: could not get orig settings: %s\n", - FL, strerror(errno)); + fprintf(stderr, FLFMT "open: could not get orig settings: %s\n", FL, + strerror(errno)); diag_tty_close(uti); return diag_pseterr(DIAG_ERR_GENERAL); } - //and set common flags + // and set common flags uti->st_cur = uti->st_orig; /* "stty raw"-like iflag settings: */ /* Clear a bunch of un-needed flags */ - uti->st_cur.c_iflag &= ~ (IGNBRK | BRKINT | IGNPAR | PARMRK - | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXOFF - | IXANY | IMAXBEL); + uti->st_cur.c_iflag &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | + INLCR | IGNCR | ICRNL | IXON | IXOFF | IXANY | IMAXBEL); #ifdef __linux__ - uti->st_cur.c_iflag &= ~(IUCLC); /* non-posix; disable ucase/lcase conversion */ + uti->st_cur.c_iflag &= ~(IUCLC); /* non-posix; disable ucase/lcase conversion */ #endif - uti->st_cur.c_oflag &= ~(OPOST); //disable impl-defined output processing + uti->st_cur.c_oflag &= ~(OPOST); // disable impl-defined output processing /* Disable canonical input and keyboard signals. +* There is no need to also clear the many ECHOXX flags, both because @@ -218,35 +224,37 @@ ttyp *diag_tty_open(const char *portname) { */ /* CJH: However, taking 'man termios' at its word, the ECHO flag is *not* affected by ICANON, and it seems we do need to clear it */ - uti->st_cur.c_lflag &= ~( ICANON | ISIG | ECHO | IEXTEN); + uti->st_cur.c_lflag &= ~(ICANON | ISIG | ECHO | IEXTEN); - uti->st_cur.c_cflag &= ~( CRTSCTS ); //non-posix; disables hardware flow ctl - uti->st_cur.c_cflag |= (CLOCAL | CREAD); //ignore modem control lines; enable read + uti->st_cur.c_cflag &= ~(CRTSCTS); // non-posix; disables hardware flow ctl + uti->st_cur.c_cflag |= (CLOCAL | CREAD); // ignore modem control lines; enable read - uti->st_cur.c_cc[VMIN] = 1; //Minimum # of bytes before read() returns (default: 0!!!) + uti->st_cur.c_cc[VMIN] = 1; // Minimum # of bytes before read() returns (default: + // 0!!!) - //and update termios with new flags. + // and update termios with new flags. #ifdef USE_TERMIOS2 rv = ioctl(uti->fd, TCSETS, &uti->st_cur); rv |= ioctl(uti->fd, TCGETS2, &uti->st2_cur); #else - rv=tcsetattr(uti->fd, TCSAFLUSH, &uti->st_cur); + rv = tcsetattr(uti->fd, TCSAFLUSH, &uti->st_cur); #endif if (rv != 0) { - fprintf(stderr, FLFMT "open: can't set input flags: %s.\n", - FL, strerror(errno)); + fprintf(stderr, FLFMT "open: can't set input flags: %s.\n", FL, + strerror(errno)); diag_tty_close(uti); return diag_pseterr(DIAG_ERR_GENERAL); } - //arbitrarily set the single byte write timeout to 1ms + // arbitrarily set the single byte write timeout to 1ms uti->byte_write_timeout_us = 1000ul; return uti; } /* Close up the TTY and restore. */ -void diag_tty_close(ttyp *tty_int) { +void +diag_tty_close(ttyp *tty_int) { struct unix_tty_int *uti = tty_int; if (!uti) { @@ -255,7 +263,7 @@ void diag_tty_close(ttyp *tty_int) { if (uti->name) { free(uti->name); } -#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT==S_POSIX || SEL_TIMEOUT==S_AUTO) +#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT == S_POSIX || SEL_TIMEOUT == S_AUTO) timer_delete(uti->timerid); #endif if (uti->fd != DL0D_INVALIDHANDLE) { @@ -278,9 +286,9 @@ void diag_tty_close(ttyp *tty_int) { return; } -//internal use : _tty_setspeed, used inside diag_tty_setup. -//returns actual new speed, or 0 if failed. updates ->tty_int struct; -//should probably called last (i.e. after setting other flags) +// internal use : _tty_setspeed, used inside diag_tty_setup. +// returns actual new speed, or 0 if failed. updates ->tty_int struct; +// should probably called last (i.e. after setting other flags) /* Baud rate hell. Status in 2015 seems to be : - termios2 struct + BOTHER flag + TCSETS2 ioctl; questionable availability - ASYNC_SPD_CUST + B38400 + custom divisor trick is "deprecated", @@ -291,39 +299,36 @@ void diag_tty_close(ttyp *tty_int) { - OSX >10.4 : (unconfirmed, TODO) : IOSSIOSPEED ioctl ? - BSD ? (unconfirmed, TODO) : IOSSIOSPEED ioctl ? */ -static int _tty_setspeed(ttyp *tty_int, unsigned int spd) { +static int +_tty_setspeed(ttyp *tty_int, unsigned int spd) { struct unix_tty_int *uti = tty_int; - unsigned int spd_real; //validate baud rate precision + unsigned int spd_real; // validate baud rate precision struct termios st_new; - int spd_done=0; //flag success + int spd_done = 0; // flag success int rv, fd; fd = uti->fd; - const unsigned int std_table[] = { - 0, 50, 75, 110, - 134, 150, 200, 300, - 600, 1200, 1800, 2400, - 4800, 9600, 19200, 38400, - #ifdef B57600 - 57600, - #endif - #ifdef B115200 - 115200 - #endif + const unsigned int std_table[] = {0, 50, 75, 110, 134, 150, + 200, 300, 600, 1200, 1800, 2400, + 4800, 9600, 19200, 38400, +#ifdef B57600 + 57600, +#endif +#ifdef B115200 + 115200 +#endif }; - //std_names must match speeds in std_table ! - const speed_t std_names[] = { - B0, B50, B75, B110, - B134, B150, B200, B300, - B600, B1200, B1800, B2400, - B4800, B9600, B19200, B38400, - #ifdef B57600 - B57600, - #endif - #ifdef B115200 - B115200 - #endif + // std_names must match speeds in std_table ! + const speed_t std_names[] = {B0, B50, B75, B110, B134, B150, + B200, B300, B600, B1200, B1800, B2400, + B4800, B9600, B19200, B38400, +#ifdef B57600 + B57600, +#endif +#ifdef B115200 + B115200 +#endif }; st_new = uti->st_cur; @@ -340,32 +345,33 @@ static int _tty_setspeed(ttyp *tty_int, unsigned int spd) { if ((rv = ioctl(fd, TCSETS2, &st2)) != 0) { break; } - //re-read to get actual speed + // re-read to get actual speed if ((rv = ioctl(fd, TCGETS2, &uti->st2_cur)) != 0) { break; } spd_real = uti->st2_cur.c_ospeed; spd_done = 1; - //Setting other flags without termios2 would "erase" speed, - //unless TCGETS returns a "safe" termios? + // Setting other flags without termios2 would "erase" speed, + // unless TCGETS returns a "safe" termios? if ((rv = ioctl(fd, TCGETS, &uti->st_cur)) != 0) { break; } - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { fprintf(stderr, FLFMT "Speed set using TCSETS + BOTHER.\n", FL); } return spd_real; } if (rv != 0) { - fprintf(stderr, FLFMT "setspeed(BOTHER) ioctl failed: %s.\n", - FL, strerror(errno)); + fprintf(stderr, FLFMT "setspeed(BOTHER) ioctl failed: %s.\n", FL, + strerror(errno)); } #endif // BOTHER flag trick -#if defined(__linux__) && (SEL_TTYBAUD==S_ALT2 || SEL_TTYBAUD==S_AUTO) -//#pragma message("Warning : using deprecated ASYNC_SPD_CUST method as a fallback.") +#if defined(__linux__) && (SEL_TTYBAUD == S_ALT2 || SEL_TTYBAUD == S_AUTO) + //#pragma message("Warning : using deprecated ASYNC_SPD_CUST method as a + // fallback.") /* * Linux iX86 method of setting non-standard baud rates. @@ -381,7 +387,7 @@ static int _tty_setspeed(ttyp *tty_int, unsigned int spd) { ss_new = uti->ss_cur; /* Now, mod the "current" settings */ - ss_new.custom_divisor = ss_new.baud_base / spd; + ss_new.custom_divisor = ss_new.baud_base / spd; spd_real = ss_new.baud_base / ss_new.custom_divisor; /* Turn of other speed flags */ @@ -393,11 +399,11 @@ static int _tty_setspeed(ttyp *tty_int, unsigned int spd) { /* And tell the kernel the new settings */ if (ioctl(fd, TIOCSSERIAL, &ss_new) < 0) { - fprintf(stderr, - FLFMT "setspeed(cust): ioctl failed: %s\n", FL, strerror(errno)); + fprintf(stderr, FLFMT "setspeed(cust): ioctl failed: %s\n", FL, + strerror(errno)); return 0; } - //sucess : update current settings + // sucess : update current settings uti->ss_cur = ss_new; /* @@ -407,11 +413,13 @@ static int _tty_setspeed(ttyp *tty_int, unsigned int spd) { st_new.c_cflag &= ~CBAUD; st_new.c_cflag |= B38400; spd_done = 1; - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { - fprintf(stderr, FLFMT "Speed set using TIOCSSERIAL + ASYNC_SPD_CUST.\n", FL); + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { + fprintf(stderr, + FLFMT "Speed set using TIOCSSERIAL + ASYNC_SPD_CUST.\n", + FL); } } -#endif //deprecated ASYNC_SPD_CUST trick +#endif // deprecated ASYNC_SPD_CUST trick /* "POSIXY" version of setting non-standard baud rates. * This works at least for FreeBSD. @@ -436,13 +444,13 @@ static int _tty_setspeed(ttyp *tty_int, unsigned int spd) { while (!spd_done) { errno = 0; - int spd_nearest=0; //index of nearest std value - int32_t besterror=1000; + int spd_nearest = 0; // index of nearest std value + int32_t besterror = 1000; - for (size_t i=0; i< ARRAY_SIZE(std_table); i++) { + for (size_t i = 0; i < ARRAY_SIZE(std_table); i++) { int32_t test; test = 1000 * ((long int)spd - std_table[i]) / spd; - test = (test >= 0)? test : -test; + test = (test >= 0) ? test : -test; if (test < besterror) { besterror = test; spd_nearest = i; @@ -450,33 +458,33 @@ static int _tty_setspeed(ttyp *tty_int, unsigned int spd) { } } - #if (B9600 == 9600) && (SEL_TTYBAUD==S_ALT3 || SEL_TTYBAUD==S_AUTO) - //try feeding the speed directly - if ( !cfsetispeed(&st_new, spd) && - !cfsetospeed(&st_new, spd)) { +#if (B9600 == 9600) && (SEL_TTYBAUD == S_ALT3 || SEL_TTYBAUD == S_AUTO) + // try feeding the speed directly + if (!cfsetispeed(&st_new, spd) && !cfsetospeed(&st_new, spd)) { spd_real = spd; spd_done = 1; - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { - fprintf(stderr, FLFMT "Speed set with cfset*speed(uint).\n", FL); + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { + fprintf(stderr, + FLFMT "Speed set with cfset*speed(uint).\n", FL); } break; } - fprintf(stderr, - "cfset*speed with direct speed failed: %s\n", strerror(errno)); - #endif - if ( !cfsetispeed(&st_new, std_names[spd_nearest]) && - !cfsetospeed(&st_new, std_names[spd_nearest])) { - //spd_real already ok + fprintf(stderr, "cfset*speed with direct speed failed: %s\n", + strerror(errno)); +#endif + if (!cfsetispeed(&st_new, std_names[spd_nearest]) && + !cfsetospeed(&st_new, std_names[spd_nearest])) { + // spd_real already ok spd_done = 1; - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { - fprintf(stderr, FLFMT "Speed set with cfset*speed(B%u).\n", FL, std_table[spd_nearest]); + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { + fprintf(stderr, FLFMT "Speed set with cfset*speed(B%u).\n", + FL, std_table[spd_nearest]); } break; } - fprintf(stderr, - "cfset*speed with Bxxxx failed: %s\n", strerror(errno)); + fprintf(stderr, "cfset*speed with Bxxxx failed: %s\n", strerror(errno)); break; - } //while !spd_done for cfset*speed attempts + } // while !spd_done for cfset*speed attempts if (!spd_done) { fprintf(stderr, "Error : all attempts at changing speed failed !\n"); @@ -484,32 +492,32 @@ static int _tty_setspeed(ttyp *tty_int, unsigned int spd) { } #ifdef USE_TERMIOS2 - //should never get here anyway + // should never get here anyway return 0; #else errno = 0; - for (int retries=1; retries <=10; retries++) { + for (int retries = 1; retries <= 10; retries++) { /* Apparently this sometimes failed with EINTR, so we retry. */ - rv=tcsetattr(fd, TCSAFLUSH, &st_new); + rv = tcsetattr(fd, TCSAFLUSH, &st_new); if (rv == 0) { break; } else { - fprintf(stderr, FLFMT "Couldn't set baud rate....retry %d\n", FL, retries); + fprintf(stderr, FLFMT "Couldn't set baud rate....retry %d\n", FL, + retries); continue; } } if (rv != 0) { - fprintf(stderr, FLFMT "Can't set baud rate to %u: %s.\n", - FL, spd, strerror(errno)); + fprintf(stderr, FLFMT "Can't set baud rate to %u: %s.\n", FL, spd, + strerror(errno)); return 0; } #endif return spd_real; - } /* * Set speed/parity etc, return 0 if ok @@ -527,67 +535,67 @@ diag_tty_setup(ttyp *tty_int, const struct diag_serial_settings *pset) { assert(fd != DL0D_INVALIDHANDLE); - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { fprintf(stderr, FLFMT "setup: fd=%d, %ubps, %d bits, %d stop, parity %d\n", - FL, fd, pset->speed, pset->databits, pset->stopbits, pset->parflag); + FL, fd, pset->speed, pset->databits, pset->stopbits, + pset->parflag); } /* Copy current settings to working copy */ st_new = uti->st_cur; st_new.c_cflag &= ~CSIZE; switch (pset->databits) { - case diag_databits_8: - st_new.c_cflag |= CS8; - break; - case diag_databits_7: - st_new.c_cflag |= CS7; - break; - case diag_databits_6: - st_new.c_cflag |= CS6; - break; - case diag_databits_5: - st_new.c_cflag |= CS5; - break; - default: - fprintf(stderr, FLFMT "bad bit setting used (%d)\n", FL, pset->databits); - return diag_iseterr(DIAG_ERR_GENERAL); + case diag_databits_8: + st_new.c_cflag |= CS8; + break; + case diag_databits_7: + st_new.c_cflag |= CS7; + break; + case diag_databits_6: + st_new.c_cflag |= CS6; + break; + case diag_databits_5: + st_new.c_cflag |= CS5; + break; + default: + fprintf(stderr, FLFMT "bad bit setting used (%d)\n", FL, pset->databits); + return diag_iseterr(DIAG_ERR_GENERAL); } switch (pset->stopbits) { - case diag_stopbits_2: - st_new.c_cflag |= CSTOPB; - break; - case diag_stopbits_1: - st_new.c_cflag &= ~CSTOPB; - break; - default: - fprintf(stderr, FLFMT "bad stopbit setting used (%d)\n", - FL, pset->stopbits); - return diag_iseterr(DIAG_ERR_GENERAL); + case diag_stopbits_2: + st_new.c_cflag |= CSTOPB; + break; + case diag_stopbits_1: + st_new.c_cflag &= ~CSTOPB; + break; + default: + fprintf(stderr, FLFMT "bad stopbit setting used (%d)\n", FL, + pset->stopbits); + return diag_iseterr(DIAG_ERR_GENERAL); } switch (pset->parflag) { - case diag_par_e: - st_new.c_cflag |= PARENB; - st_new.c_cflag &= ~PARODD; - break; - case diag_par_o: - st_new.c_cflag |= (PARENB | PARODD); - break; - case diag_par_n: - st_new.c_cflag &= ~PARENB; - break; - default: - fprintf(stderr, - FLFMT "bad parity setting used (%d)\n", FL, pset->parflag); - return diag_iseterr(DIAG_ERR_GENERAL); + case diag_par_e: + st_new.c_cflag |= PARENB; + st_new.c_cflag &= ~PARODD; + break; + case diag_par_o: + st_new.c_cflag |= (PARENB | PARODD); + break; + case diag_par_n: + st_new.c_cflag &= ~PARENB; + break; + default: + fprintf(stderr, FLFMT "bad parity setting used (%d)\n", FL, pset->parflag); + return diag_iseterr(DIAG_ERR_GENERAL); } errno = 0; #ifdef USE_TERMIOS2 - rv=ioctl(fd, TCSETS, &st_new); + rv = ioctl(fd, TCSETS, &st_new); rv |= ioctl(fd, TCGETS2, &uti->st2_cur); #else - rv=tcsetattr(fd, TCSAFLUSH, &st_new); + rv = tcsetattr(fd, TCSAFLUSH, &st_new); #endif if (rv != 0) { fprintf(stderr, @@ -599,14 +607,17 @@ diag_tty_setup(ttyp *tty_int, const struct diag_serial_settings *pset) { return diag_iseterr(DIAG_ERR_GENERAL); } - //update current settings + // update current settings uti->st_cur = st_new; #if defined(_POSIX_TIMERS) || defined(__linux__) - //calculate write timeout for a single byte - //gross bits per byte: 1 start bit + count of data bits + count of stop bits + parity bit, if set - int gross_bits_per_byte = 1 + pset->databits + pset->stopbits + (pset->parflag == diag_par_n ? 0 : 1); - //single byte timeout to: (gross_bits_per_byte / (baudrate[1/s]/1000000[us/s]))[us]; + // calculate write timeout for a single byte + // gross bits per byte: 1 start bit + count of data bits + count of stop bits + + // parity bit, if set + int gross_bits_per_byte = 1 + pset->databits + pset->stopbits + + (pset->parflag == diag_par_n ? 0 : 1); + // single byte timeout to: (gross_bits_per_byte / + // (baudrate[1/s]/1000000[us/s]))[us]; uti->byte_write_timeout_us = (gross_bits_per_byte * 1000000ul / pset->speed); #endif @@ -614,27 +625,27 @@ diag_tty_setup(ttyp *tty_int, const struct diag_serial_settings *pset) { if (!spd_real) { return diag_iseterr(DIAG_ERR_GENERAL); } - //warn if actual speed is far off - spd_err = ((long int)spd_real - pset->speed)*100 / pset->speed; - spd_err = (spd_err >=0)? spd_err: -spd_err; + // warn if actual speed is far off + spd_err = ((long int)spd_real - pset->speed) * 100 / pset->speed; + spd_err = (spd_err >= 0) ? spd_err : -spd_err; if (spd_err >= 5) { fprintf(stderr, "Warning : speed off by >= 5%% !\n"); } - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { - fprintf(stderr, FLFMT "Speed set to %u, error~%ld%%\n", FL, - spd_real, spd_err); + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { + fprintf(stderr, FLFMT "Speed set to %u, error~%ld%%\n", FL, spd_real, + spd_err); } return 0; -} //diag_tty_setup +} // diag_tty_setup /* * Set/Clear DTR and RTS lines, as specified */ int -diag_tty_control(ttyp *tty_int, unsigned int dtr, unsigned int rts) { - int flags; /* Current flag values. */ +diag_tty_control(ttyp *tty_int, unsigned int dtr, unsigned int rts) { + int flags; /* Current flag values. */ struct unix_tty_int *uti = tty_int; int setflags = 0, clearflags = 0; @@ -652,21 +663,21 @@ diag_tty_control(ttyp *tty_int, unsigned int dtr, unsigned int rts) { errno = 0; if (ioctl(uti->fd, TIOCMGET, &flags) < 0) { - fprintf(stderr, - FLFMT "open: Ioctl TIOCMGET failed %s\n", FL, strerror(errno)); + fprintf(stderr, FLFMT "open: Ioctl TIOCMGET failed %s\n", FL, + strerror(errno)); return diag_iseterr(DIAG_ERR_GENERAL); } flags |= setflags; flags &= ~clearflags; if (ioctl(uti->fd, TIOCMSET, &flags) < 0) { - fprintf(stderr, - FLFMT "open: Ioctl TIOCMSET failed %s\n", FL, strerror(errno)); + fprintf(stderr, FLFMT "open: Ioctl TIOCMSET failed %s\n", FL, + strerror(errno)); return diag_iseterr(DIAG_ERR_GENERAL); } - if (diag_l0_debug & DIAG_DEBUG_TIMER) { - unsigned long tc=diag_os_getms(); + if (diag_l0_debug_load() & DIAG_DEBUG_TIMER) { + unsigned long tc = diag_os_getms(); fprintf(stderr, FLFMT "%lu : DTR/RTS changed\n", FL, tc); } @@ -678,7 +689,7 @@ diag_tty_control(ttyp *tty_int, unsigned int dtr, unsigned int rts) { // But write timeouts should be very rare, and are considered an error ssize_t diag_tty_write(ttyp *tty_int, const void *buf, const size_t count) { -#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT==S_POSIX || SEL_TIMEOUT==S_AUTO) +#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT == S_POSIX || SEL_TIMEOUT == S_AUTO) ssize_t rv; struct unix_tty_int *uti = tty_int; size_t n; @@ -691,34 +702,38 @@ diag_tty_write(ttyp *tty_int, const void *buf, const size_t count) { assert(count > 0); - //the timeout (the port is opened in blocking mode, and we don't want it to block indefinitely); - //the single byte timeout * count of bytes + 10ms (10 thousand microseconds; an arbitrary value) + // the timeout (the port is opened in blocking mode, and we don't want it to block + // indefinitely); the single byte timeout * count of bytes + 10ms (10 thousand + // microseconds; an arbitrary value) long unsigned int timeout = uti->byte_write_timeout_us * count + 10000ul; it.it_value.tv_sec = (time_t)(timeout / 1000000ul); - it.it_value.tv_nsec = (long)(timeout % 1000000ul)*1000l; //multiply by 1000 to get number of nanoseconds - //set interval to PT_REPEAT to make sure we don't block inside read() - it.it_interval.tv_sec=0; + it.it_value.tv_nsec = (long)(timeout % 1000000ul) * 1000l; // multiply by 1000 to + // get number of + // nanoseconds + // set interval to PT_REPEAT to make sure we don't block inside read() + it.it_interval.tv_sec = 0; it.it_interval.tv_nsec = PT_REPEAT * 1000; - uti->pt_expired=0; - //arm the timer + uti->pt_expired = 0; + // arm the timer timer_settime(uti->timerid, 0, &it, NULL); - n=0; + n = 0; while (n < count) { if (uti->pt_expired) { break; } - rv = write(uti->fd, &p[n], count-n); + rv = write(uti->fd, &p[n], count - n); if (rv < 0) { if (errno == EINTR) { - //not an error, just interrupted (probably a signal handler) + // not an error, just interrupted (probably a signal + // handler) rv = 0; errno = 0; } else { - //real error: + // real error: break; } } else { @@ -726,36 +741,37 @@ diag_tty_write(ttyp *tty_int, const void *buf, const size_t count) { } } - //disarm the timer in case it hasn't expired yet + // disarm the timer in case it hasn't expired yet it.it_value.tv_sec = it.it_value.tv_nsec = 0; timer_settime(uti->timerid, 0, &it, NULL); if (rv < 0) { - //errors other than EINTR - fprintf(stderr, FLFMT "write to fd %d returned %s.\n", FL, uti->fd, strerror(errno)); + // errors other than EINTR + fprintf(stderr, FLFMT "write to fd %d returned %s.\n", FL, uti->fd, + strerror(errno)); return diag_iseterr(DIAG_ERR_GENERAL); } - //wait until the data is transmitted -#ifdef USE_TERMIOS2 + // wait until the data is transmitted +# ifdef USE_TERMIOS2 /* no exact equivalent ioctl for tcdrain, but TCSBRK with arg !=0 is "treated like tcdrain(fd)" according to info tty_ioctl */ if (ioctl(uti->fd, TCSBRK, 1) != 0) { - static int tcsb_warned=0; + static int tcsb_warned = 0; if (!tcsb_warned) { fprintf(stderr, "TCSBRK doesn't work!\n"); } - tcsb_warned=1; + tcsb_warned = 1; } -#else +# else tcdrain(uti->fd); -#endif +# endif return rv; -} //_POSIX_TIMERS tty_write() +} //_POSIX_TIMERS tty_write() -#elif (SEL_TIMEOUT==S_LINUX || SEL_TIMEOUT==S_OTHER || SEL_TIMEOUT==S_AUTO) +#elif (SEL_TIMEOUT == S_LINUX || SEL_TIMEOUT == S_OTHER || SEL_TIMEOUT == S_AUTO) /* No POSIX timers, this should be OK for everything else * Technique: write loop, manually check timeout */ @@ -770,7 +786,7 @@ diag_tty_write(ttyp *tty_int, const void *buf, const size_t count) { long unsigned int timeout = uti->byte_write_timeout_us * count + 10000ul; t1 = diag_os_gethrt(); - p = (const uint8_t *)buf; /* For easy pointer I/O */ + p = (const uint8_t *)buf; /* For easy pointer I/O */ n = 0; expired = 0; errno = 0; @@ -778,11 +794,11 @@ diag_tty_write(ttyp *tty_int, const void *buf, const size_t count) { while ((c > 0) && !expired) { t2 = diag_os_hrtus(diag_os_gethrt() - t1); if (t2 >= timeout) { - expired=1; + expired = 1; break; } - rv = write(uti->fd, &p[n], c); + rv = write(uti->fd, &p[n], c); if (rv == -1 && errno == EINTR) { rv = 0; errno = 0; @@ -797,32 +813,32 @@ diag_tty_write(ttyp *tty_int, const void *buf, const size_t count) { } if (n > 0 || rv >= 0) { - //wait until the data is transmitted -#ifdef USE_TERMIOS2 + // wait until the data is transmitted +# ifdef USE_TERMIOS2 /* no exact equivalent ioctl for tcdrain, but - "TCSBRK : [...] treat tcsendbreak(fd,arg) with nonzero arg like tcdrain(fd)." + "TCSBRK : [...] treat tcsendbreak(fd,arg) with nonzero arg like + tcdrain(fd)." */ ioctl(uti->fd, TCSBRK, 1); -#else +# else tcdrain(uti->fd); -#endif +# endif return n; } - fprintf(stderr, FLFMT "write to fd %d returned %s.\n", - FL, uti->fd, strerror(errno)); + fprintf(stderr, FLFMT "write to fd %d returned %s.\n", FL, uti->fd, + strerror(errno)); /* Unspecific Error */ return diag_iseterr(DIAG_ERR_GENERAL); -} //S_OTHER || S_LINUX write implem +} // S_OTHER || S_LINUX write implem #else - #error Fell in the cracks of implementation selectors ! -#endif //tty_write() implementations - +# error Fell in the cracks of implementation selectors ! +#endif // tty_write() implementations ssize_t diag_tty_read(ttyp *tty_int, void *buf, size_t count, unsigned int timeout) { -#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT==S_POSIX || SEL_TIMEOUT==S_AUTO) +#if defined(_POSIX_TIMERS) && (SEL_TIMEOUT == S_POSIX || SEL_TIMEOUT == S_AUTO) ssize_t rv; size_t n; int expired; @@ -831,18 +847,18 @@ diag_tty_read(ttyp *tty_int, void *buf, size_t count, unsigned int timeout) { struct itimerspec it; - assert((count > 0) && ( timeout > 0) && (timeout < MAXTIMEOUT)); - //the timeout + assert((count > 0) && (timeout > 0) && (timeout < MAXTIMEOUT)); + // the timeout it.it_value.tv_sec = timeout / 1000; it.it_value.tv_nsec = (timeout % 1000) * 1000000; - //set interval to PT_REPEAT to make sure we don't block inside read() - it.it_interval.tv_sec=0; + // set interval to PT_REPEAT to make sure we don't block inside read() + it.it_interval.tv_sec = 0; it.it_interval.tv_nsec = PT_REPEAT * 1000; - uti->pt_expired=0; - expired=0; + uti->pt_expired = 0; + expired = 0; - //arm the timer + // arm the timer timer_settime(uti->timerid, 0, &it, NULL); n = 0; @@ -851,18 +867,18 @@ diag_tty_read(ttyp *tty_int, void *buf, size_t count, unsigned int timeout) { while (n < count) { if (uti->pt_expired) { - expired=1; + expired = 1; break; } - rv = read(uti->fd, &p[n], count-n); + rv = read(uti->fd, &p[n], count - n); if (rv < 0) { if (errno == EINTR) { - //not an error, just an interrupted syscall + // not an error, just an interrupted syscall rv = 0; errno = 0; } else { - //real error: + // real error: break; } } else { @@ -870,11 +886,12 @@ diag_tty_read(ttyp *tty_int, void *buf, size_t count, unsigned int timeout) { } } - //always disarm the timer + // always disarm the timer it.it_value.tv_sec = it.it_value.tv_nsec = 0; timer_settime(uti->timerid, 0, &it, NULL); - //if anything has been read, then return the number of read bytes; return timeout error otherwise + // if anything has been read, then return the number of read bytes; return timeout + // error otherwise if (rv >= 0) { if (n > 0) { return n; @@ -884,16 +901,17 @@ diag_tty_read(ttyp *tty_int, void *buf, size_t count, unsigned int timeout) { } } - //errors other than EINTR - fprintf(stderr, FLFMT "read on fd %d returned %s.\n", FL, uti->fd, strerror(errno)); + // errors other than EINTR + fprintf(stderr, FLFMT "read on fd %d returned %s.\n", FL, uti->fd, + strerror(errno)); - //Unspecified error + // Unspecified error return diag_iseterr(DIAG_ERR_GENERAL); -} //POSIX read implem +} // POSIX read implem -#elif (SEL_TIMEOUT==S_OTHER || SEL_TIMEOUT == S_AUTO) - //no posix timers and it's not linux - //Loop with { select() with a timeout; +#elif (SEL_TIMEOUT == S_OTHER || SEL_TIMEOUT == S_AUTO) + // no posix timers and it's not linux + // Loop with { select() with a timeout; // read() ; manually check timeout} ssize_t rv; @@ -903,21 +921,21 @@ diag_tty_read(ttyp *tty_int, void *buf, size_t count, unsigned int timeout) { struct unix_tty_int *uti = tty_int; int expired = 0; - tstart=diag_os_gethrt(); - incr = timeout * 1000; //us + tstart = diag_os_gethrt(); + incr = timeout * 1000; // us - if (diag_l0_debug & DIAG_DEBUG_TIMER) { - fprintf(stderr, "timeout=%u, start=%llu, delta=%llu\n", - timeout, tstart, incr); + if (diag_l0_debug_load() & DIAG_DEBUG_TIMER) { + fprintf(stderr, "timeout=%u, start=%llu, delta=%llu\n", timeout, tstart, + incr); } errno = 0; - p = (uint8_t *)buf; /* For easy pointer I/O */ + p = (uint8_t *)buf; /* For easy pointer I/O */ n = 0; while (count > 0 && expired == 0) { - //select() loop to ensure read() won't block: - while ( !expired ) { + // select() loop to ensure read() won't block: + while (!expired) { fd_set set; struct timeval tv; unsigned long long rmn; @@ -927,54 +945,56 @@ diag_tty_read(ttyp *tty_int, void *buf, size_t count, unsigned int timeout) { if (tdone_us >= incr) { expired = 1; - rv=0; + rv = 0; goto finished; } - rmn = timeout*1000 - tdone_us; //remaining before timeout + rmn = timeout * 1000 - tdone_us; // remaining before timeout FD_ZERO(&set); FD_SET(uti->fd, &set); - tv.tv_sec = rmn / (1000*1000); - tv.tv_usec = rmn % (1000*1000); + tv.tv_sec = rmn / (1000 * 1000); + tv.tv_usec = rmn % (1000 * 1000); - rv = select( uti->fd + 1, &set, NULL, NULL, &tv ); + rv = select(uti->fd + 1, &set, NULL, NULL, &tv); // 4 possibilities here: // EINTR => retry // FD ready => break // timed out => retry (will DIAG_ERR_TIMEOUT) // other errors => diag_iseterr if ((rv < 0) && (errno == EINTR)) { - rv=0; - errno=0; + rv = 0; + errno = 0; continue; } if (FD_ISSET(uti->fd, &set)) { - //fd is ready: + // fd is ready: break; } if (rv < 0) { - fprintf(stderr, FLFMT "select() error: %s.\n", FL, strerror(errno)); + fprintf(stderr, FLFMT "select() error: %s.\n", FL, + strerror(errno)); return diag_iseterr(DIAG_ERR_GENERAL); } - } //select loop + } // select loop - rv = read(uti->fd, &p[n], count); + rv = read(uti->fd, &p[n], count); if ((rv < 0) && (rv == EINTR)) { - rv=0; - errno=0; + rv = 0; + errno = 0; continue; } - if (rv<=0) { - fprintf(stderr, FLFMT "read() says %zu: %s.\n", FL, rv, strerror(errno)); + if (rv <= 0) { + fprintf(stderr, FLFMT "read() says %zu: %s.\n", FL, rv, + strerror(errno)); break; } count -= rv; n += rv; - } //total read loop + } // total read loop finished: if (rv >= 0) { if (n > 0) @@ -983,132 +1003,140 @@ diag_tty_read(ttyp *tty_int, void *buf, size_t count, unsigned int timeout) { return DIAG_ERR_TIMEOUT; } - fprintf(stderr, FLFMT "read() returned %s.\n", - FL, strerror(errno)); + fprintf(stderr, FLFMT "read() returned %s.\n", FL, strerror(errno)); /* Unspecified Error */ return diag_iseterr(DIAG_ERR_GENERAL); -} //S_OTHER read implem +} // S_OTHER read implem -#elif defined(__linux__) && (SEL_TIMEOUT==S_LINUX || SEL_TIMEOUT==S_AUTO) +#elif defined(__linux__) && (SEL_TIMEOUT == S_LINUX || SEL_TIMEOUT == S_AUTO) -/* - * We have to read to loop since we've cleared SA_RESTART. - * - * This implementation uses /dev/rtc to time out, but seems flawed : it - * also relies on select() to guarantee that (count) bytes are available. - * - * Also, it calls select() very very often (why is tv={0} ?) - */ + /* + * We have to read to loop since we've cleared SA_RESTART. + * + * This implementation uses /dev/rtc to time out, but seems flawed : it + * also relies on select() to guarantee that (count) bytes are available. + * + * Also, it calls select() very very often (why is tv={0} ?) + */ - struct timeval tv; - unsigned int time; - int rv,fd,retval; - unsigned long data; - struct unix_tty_int *uti = tty_int;; + struct timeval tv; + unsigned int time; + int rv, fd, retval; + unsigned long data; + struct unix_tty_int *uti = tty_int; + ; - assert((timeout < MAXTIMEOUT) && (count > 0)); + assert((timeout < MAXTIMEOUT) && (count > 0)); - if (diag_l0_debug & DIAG_DEBUG_READ) { - fprintf(stderr, FLFMT "Entered diag_tty_read with count=%u, timeout=%ums\n", FL, - (unsigned int) count, timeout); - } + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { + fprintf(stderr, + FLFMT + "Entered diag_tty_read with count=%u, " + "timeout=%ums\n", + FL, (unsigned int)count, timeout); + } - errno = 0; - time = 0; + errno = 0; + time = 0; - tv.tv_sec = 0; - tv.tv_usec = 0; + tv.tv_sec = 0; + tv.tv_usec = 0; - timeout = (int)((unsigned long) timeout * 2048/1000); //watch for overflow ! + timeout = (int)((unsigned long)timeout * 2048 / 1000); // watch for + // overflow ! - fd = open ("/dev/rtc", O_RDONLY); - if (fd <=0) { - fprintf(stderr, FLFMT "diag_tty_read: error opening /dev/rtc !\n", FL); - perror("\t"); - return diag_iseterr(DIAG_ERR_GENERAL); - } + fd = open("/dev/rtc", O_RDONLY); + if (fd <= 0) { + fprintf(stderr, FLFMT "diag_tty_read: error opening /dev/rtc !\n", + FL); + perror("\t"); + return diag_iseterr(DIAG_ERR_GENERAL); + } - /* Read periodic IRQ rate */ - retval = ioctl(fd, RTC_IRQP_READ, &data); + /* Read periodic IRQ rate */ + retval = ioctl(fd, RTC_IRQP_READ, &data); - if (retval != 2048) - ioctl(fd, RTC_IRQP_SET, 2048); + if (retval != 2048) + ioctl(fd, RTC_IRQP_SET, 2048); - /* Enable periodic interrupts */ - ioctl(fd, RTC_PIE_ON, 0); + /* Enable periodic interrupts */ + ioctl(fd, RTC_PIE_ON, 0); - read(fd, &data, sizeof(unsigned long)); - data >>= 8; - time+=data; + read(fd, &data, sizeof(unsigned long)); + data >>= 8; + time += data; - while ( 1 ) { - fd_set set; + while (1) { + fd_set set; - FD_ZERO(&set); - FD_SET(uti->fd, &set); + FD_ZERO(&set); + FD_SET(uti->fd, &set); - rv = select ( uti->fd + 1, &set, NULL, NULL, &tv ) ; + rv = select(uti->fd + 1, &set, NULL, NULL, &tv); - if ( rv > 0 ) break ; + if (rv > 0) + break; - if (errno != 0 && errno != EINTR) break; - errno = 0 ; + if (errno != 0 && errno != EINTR) + break; + errno = 0; - read(fd, &data, sizeof(unsigned long)); - data >>= 8; - time+=data; - if (time>=timeout) - break; - } + read(fd, &data, sizeof(unsigned long)); + data >>= 8; + time += data; + if (time >= timeout) + break; + } - /* Disable periodic interrupts */ - ioctl(fd, RTC_PIE_OFF, 0); - close(fd); + /* Disable periodic interrupts */ + ioctl(fd, RTC_PIE_OFF, 0); + close(fd); - if (diag_l0_debug & DIAG_DEBUG_IOCTL) - if (time>=timeout) { - fprintf(stderr, FLFMT "timed out: %ums\n",FL,timeout*1000/2048); - } + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) + if (time >= timeout) { + fprintf(stderr, FLFMT "timed out: %ums\n", FL, + timeout * 1000 / 2048); + } - switch (rv) { - case 0: - /* Timeout */ - //this doesn't require a diag_iseterr() call, as is the case when diag_tty_read - //is called to flush - return DIAG_ERR_TIMEOUT; - case 1: - /* Ready for read */ - rv = 0; - /* - * XXX Won't you hang here if "count" bytes don't arrive? - * XXX Yes, possibly ! - */ - rv = read(uti->fd, buf, count); - if ((diag_l0_debug & DIAG_DEBUG_READ) && (rv<=0)) - fprintf(stderr, "read() returned %d?", rv); - return rv; + switch (rv) { + case 0: + /* Timeout */ + // this doesn't require a diag_iseterr() call, as is the case when + // diag_tty_read is called to flush + return DIAG_ERR_TIMEOUT; + case 1: + /* Ready for read */ + rv = 0; + /* + * XXX Won't you hang here if "count" bytes don't arrive? + * XXX Yes, possibly ! + */ + rv = read(uti->fd, buf, count); + if ((diag_l0_debug_load() & DIAG_DEBUG_READ) && (rv <= 0)) + fprintf(stderr, "read() returned %d?", rv); + return rv; - default: - fprintf(stderr, FLFMT "select on fd %d returned %s.\n", - FL, uti->fd, strerror(errno)); + default: + fprintf(stderr, FLFMT "select on fd %d returned %s.\n", FL, + uti->fd, strerror(errno)); - /* Unspecific Error */ - return diag_iseterr(DIAG_ERR_GENERAL); - } -} //S_LINUX read implem + /* Unspecific Error */ + return diag_iseterr(DIAG_ERR_GENERAL); + } + } // S_LINUX read implem #else - #error Fell in the cracks of implementation selectors ! +# error Fell in the cracks of implementation selectors ! #endif //_tty_read() implementations - /* * POSIX serial I/O input flush + * diag_tty_read with IFLUSH_TIMEOUT. * Ret 0 if ok */ -int diag_tty_iflush(ttyp *tty_int) { +int +diag_tty_iflush(ttyp *tty_int) { uint8_t buf[MAXRBUF]; int rv; struct unix_tty_int *uti = tty_int; @@ -1116,78 +1144,75 @@ int diag_tty_iflush(ttyp *tty_int) { errno = 0; #ifdef USE_TERMIOS2 - rv=ioctl(uti->fd, TCFLSH, TCIFLUSH); + rv = ioctl(uti->fd, TCFLSH, TCIFLUSH); #else - rv=tcflush(uti->fd, TCIFLUSH); + rv = tcflush(uti->fd, TCIFLUSH); #endif // USE_TERMIOS2 - if ( rv != 0) { - fprintf(stderr, FLFMT "TCIFLUSH on fd %d returned %s.\n", - FL, uti->fd, strerror(errno)); + if (rv != 0) { + fprintf(stderr, FLFMT "TCIFLUSH on fd %d returned %s.\n", FL, uti->fd, + strerror(errno)); } /* Read any old data hanging about on the port */ rv = diag_tty_read(uti, buf, sizeof(buf), IFLUSH_TIMEOUT); - if ((rv > 0) && (diag_l0_debug & DIAG_DEBUG_DATA)) { - fprintf(stderr, FLFMT "tty_iflush: >=%d junk bytes discarded: 0x%X...\n", FL, rv, buf[0]); -// diag_data_dump(stderr, buf, rv); //could flood the screen -// fprintf(stderr, "\n"); + if ((rv > 0) && (diag_l0_debug_load() & DIAG_DEBUG_DATA)) { + fprintf(stderr, FLFMT "tty_iflush: >=%d junk bytes discarded: 0x%X...\n", + FL, rv, buf[0]); + // diag_data_dump(stderr, buf, rv); //could + // flood the screen fprintf(stderr, "\n"); } return 0; -} //diag_tty_iflush - - +} // diag_tty_iflush // ideally use TIOCSBRK, if defined (probably in sys/ioctl.h) -int diag_tty_break(ttyp *tty_int, const unsigned int ms) { +int +diag_tty_break(ttyp *tty_int, const unsigned int ms) { #ifdef TIOCSBRK -// TIOCSBRK: set TX break until TIOCCBRK. Ideal for our use but not in POSIX. -/* - * This one returns right after clearing the break. This is more generic and - * can be used to bit-bang a 5bps byte. - */ + // TIOCSBRK: set TX break until TIOCCBRK. Ideal for our use but not in POSIX. + /* + * This one returns right after clearing the break. This is more generic and + * can be used to bit-bang a 5bps byte. + */ struct unix_tty_int *uti = tty_int; -#ifdef USE_TERMIOS2 +# ifdef USE_TERMIOS2 /* no exact equivalent ioctl for tcdrain, but "TCSBRK : [...] treat tcsendbreak(fd,arg) with nonzero arg like tcdrain(fd)." */ ioctl(uti->fd, TCSBRK, 1); -#else +# else if (tcdrain(uti->fd)) { - fprintf(stderr, FLFMT "tcdrain returned %s.\n", - FL, strerror(errno)); + fprintf(stderr, FLFMT "tcdrain returned %s.\n", FL, strerror(errno)); return diag_iseterr(DIAG_ERR_GENERAL); } -#endif +# endif if (ioctl(uti->fd, TIOCSBRK, 0) < 0) { - fprintf(stderr, - FLFMT "open: Ioctl TIOCSBRK failed %s\n", FL, strerror(errno)); + fprintf(stderr, FLFMT "open: Ioctl TIOCSBRK failed %s\n", FL, + strerror(errno)); return diag_iseterr(DIAG_ERR_GENERAL); } diag_os_millisleep(ms); if (ioctl(uti->fd, TIOCCBRK, 0) < 0) { - fprintf(stderr, - FLFMT "open: Ioctl TIOCCBRK failed %s\n", FL, strerror(errno)); + fprintf(stderr, FLFMT "open: Ioctl TIOCCBRK failed %s\n", FL, + strerror(errno)); return diag_iseterr(DIAG_ERR_GENERAL); } return 0; #else -#warning ******* Dont know how to implement diag_tty_break() on your OS ! -#warning ******* Compiling diag_tty_break with a fixed 25ms setbreak ! -#warning ******* DUMB interfaces may not work properly !! - if (ms<25) +# warning ******* Dont know how to implement diag_tty_break() on your OS ! +# warning ******* Compiling diag_tty_break with a fixed 25ms setbreak ! +# warning ******* DUMB interfaces may not work properly !! + if (ms < 25) return 0; return diag_tty_fastbreak(uti, ms); -#endif //if .. for diag_tty_break -} //diag_tty_break - - +#endif // if .. for diag_tty_break +} // diag_tty_break /* * diag_tty_fastbreak @@ -1197,10 +1222,11 @@ int diag_tty_break(ttyp *tty_int, const unsigned int ms) { * we'll probably have to add a ->pset member to diag_l0_device to store the * "desired" setting. And use that to call diag_tty_setup to restore settings... */ -int diag_tty_fastbreak(ttyp *tty_int, const unsigned int ms) { - struct unix_tty_int *uti=tty_int; +int +diag_tty_fastbreak(ttyp *tty_int, const unsigned int ms) { + struct unix_tty_int *uti = tty_int; uint8_t cbuf; - unsigned long long tv1,tv2,tvdiff; + unsigned long long tv1, tv2, tvdiff; struct diag_serial_settings set; unsigned int msremain; @@ -1222,19 +1248,19 @@ int diag_tty_fastbreak(ttyp *tty_int, const unsigned int ms) { tv1 = diag_os_gethrt(); /* Send a 0x00 byte message */ diag_tty_write(uti, "", 1); - //Alternate method ; we can write() ourselves and then tcdrain() to make - //sure data is sent ? + // Alternate method ; we can write() ourselves and then tcdrain() to make + // sure data is sent ? /* * And read back the single byte echo, which shows TX completes - */ + */ if (diag_tty_read(uti, &cbuf, 1, 1000) != 1) { fprintf(stderr, FLFMT "tty_fastbreak: echo read error\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } - //we probably have a few ms left; - //restore 10400bps: + // we probably have a few ms left; + // restore 10400bps: set.speed = 10400; if (diag_tty_setup(uti, &set)) { fprintf(stderr, FLFMT "Could not restore settings after fastbreak!\n", FL); @@ -1242,8 +1268,8 @@ int diag_tty_fastbreak(ttyp *tty_int, const unsigned int ms) { } /* Now wait the requested number of ms */ - tv2=diag_os_gethrt(); - tvdiff = diag_os_hrtus(tv2 - tv1); //us + tv2 = diag_os_gethrt(); + tvdiff = diag_os_hrtus(tv2 - tv1); // us if (tvdiff >= (ms * 1000)) { return 0; // already finished @@ -1253,21 +1279,22 @@ int diag_tty_fastbreak(ttyp *tty_int, const unsigned int ms) { diag_os_millisleep(msremain); - tv2=diag_os_gethrt(); - tvdiff = diag_os_hrtus(tv2 - tv1); //us + tv2 = diag_os_gethrt(); + tvdiff = diag_os_hrtus(tv2 - tv1); // us - //XXX this message may need to be removed if timing is impaired - if (diag_l0_debug & DIAG_DEBUG_TIMER) { + // XXX this message may need to be removed if timing is impaired + if (diag_l0_debug_load() & DIAG_DEBUG_TIMER) { fprintf(stderr, FLFMT "Fast break finished : tWUP=%llu\n", FL, tvdiff); } return 0; } -//ret true if pname is a tty -static bool test_ttyness(const char *pname) { - int testfd = -1; // file descriptor for tested device files - bool yes=0; +// ret true if pname is a tty +static bool +test_ttyness(const char *pname) { + int testfd = -1; // file descriptor for tested device files + bool yes = 0; testfd = open(pname, O_RDWR | O_NOCTTY | O_NDELAY); if (testfd != -1) { @@ -1284,33 +1311,35 @@ static bool test_ttyness(const char *pname) { * Adapted from FreeSSM : * https://github.com/Comer352L/FreeSSM */ -char **diag_tty_getportlist(int *numports) { - char ffn[256] = ""; // full filename incl. path - const char *devroot="/dev/"; - const char *devusbroot="/dev/usb"; +char ** +diag_tty_getportlist(int *numports) { + char ffn[256] = ""; // full filename incl. path + const char *devroot = "/dev/"; + const char *devusbroot = "/dev/usb"; DIR *dp = NULL; struct dirent *fp = NULL; char **portlist = NULL; - int elems; //temp number of ports + int elems; // temp number of ports assert(numports != NULL); *numports = 0; elems = 0; /* 1: iterate in /dev/ */ - dp = opendir (devroot); + dp = opendir(devroot); if (dp != NULL) { while (1) { - fp = readdir (dp); // get next file in directory + fp = readdir(dp); // get next file in directory if (fp == NULL) { break; } - if ((!strncmp(fp->d_name,"ttyS",4)) || - (!strncmp(fp->d_name,"ttyUSB",6)) || - (!strncmp(fp->d_name,"ttyACM",6))) { + if ((!strncmp(fp->d_name, "ttyS", 4)) || + (!strncmp(fp->d_name, "ttyUSB", 6)) || + (!strncmp(fp->d_name, "ttyACM", 6))) { // CONSTRUCT FULL FILENAME: strcpy(ffn, devroot); - strncat(ffn, fp->d_name, ARRAY_SIZE(ffn) - strlen(devroot) - 1); + strncat(ffn, fp->d_name, + ARRAY_SIZE(ffn) - strlen(devroot) - 1); if (!test_ttyness(ffn)) { continue; @@ -1325,21 +1354,22 @@ char **diag_tty_getportlist(int *numports) { elems++; } } - closedir (dp); + closedir(dp); } /* iterate in /dev/usb */ - dp = opendir (devusbroot); + dp = opendir(devusbroot); if (dp != NULL) { while (1) { - fp = readdir (dp); // get next file in directory + fp = readdir(dp); // get next file in directory if (fp == NULL) { break; } - if (!strncmp(fp->d_name,"ttyUSB",6)) { + if (!strncmp(fp->d_name, "ttyUSB", 6)) { // CONSTRUCT FULL FILENAME: strcpy(ffn, devusbroot); - strncat(ffn, fp->d_name, ARRAY_SIZE(ffn) - strlen(devusbroot) - 1); + strncat(ffn, fp->d_name, + ARRAY_SIZE(ffn) - strlen(devusbroot) - 1); if (!test_ttyness(ffn)) { continue; @@ -1353,11 +1383,10 @@ char **diag_tty_getportlist(int *numports) { portlist = templist; elems++; } - } //while - closedir (dp); + } // while + closedir(dp); } *numports = elems; return portlist; } - diff --git a/scantool/diag_tty_unix.h b/scantool/diag_tty_unix.h index 72d62ca1..f947ca74 100644 --- a/scantool/diag_tty_unix.h +++ b/scantool/diag_tty_unix.h @@ -35,45 +35,43 @@ extern "C" { #endif - #include /****** OS-specific implementation selectors ******/ -/* These are for testing/debugging only, to force compilation of certain implementations - for diag_tty* and diag_os* functions. +/* These are for testing/debugging only, to force compilation of certain + implementations for diag_tty* and diag_os* functions. ### Map of features with more than one implementation related to POSIX ### ## tty-related features ## SEL_TIMEOUT: diag_tty_{read,write}() timeouts - S_POSIX) needs _POSIX_TIMERS, uses timer_create + sigaction for a SIGUSR1 handler - S_OTHER) use select(timeout) + read + manual timeout check loop - S_LINUX) needs __linux__ && /dev/rtc - X) (ugly, not implemented) : increase OS periodic callback frequency, control timeout manually - SEL_TTYOPEN: diag_tty_open() : open() flags: - ALT1) needs O_NONBLOCK; open non-blocking then clear flag - ALT2) don't set O_NONBLOCK. + S_POSIX) needs _POSIX_TIMERS, uses timer_create + sigaction for a SIGUSR1 + handler S_OTHER) use select(timeout) + read + manual timeout check loop S_LINUX) needs + __linux__ && /dev/rtc X) (ugly, not implemented) : increase OS periodic callback + frequency, control timeout manually SEL_TTYOPEN: diag_tty_open() : open() flags: ALT1) + needs O_NONBLOCK; open non-blocking then clear flag ALT2) don't set O_NONBLOCK. SEL_TTYBAUD: diag_tty_setup() : tty settings (bps, parity etc) ALT1) needs __linux__ : termios2 + BOTHER ALT2) needs __linux__ : uses TIOCSSERIAL, ASYNC_SPD_CUST, CBAUD. - ALT3) needs "B9600 == 9600" etc. Calls cfset{i,o}speed with speed in bps (very non-portable) - ALTx) picks nearest standard Bxxxx; calls cfset{i,o}speed (universal fallback) + ALT3) needs "B9600 == 9600" etc. Calls cfset{i,o}speed with speed in bps + (very non-portable) ALTx) picks nearest standard Bxxxx; calls cfset{i,o}speed (universal + fallback) ###### For every feature listed above, it's possible to force compilation of a specific implementation using the #defines below. TODO: add compile tests to cmake? */ -#define S_AUTO 0 +#define S_AUTO 0 /* First set, for obviously OS-dependant features: */ -#define S_POSIX 1 -#define S_LINUX 2 +#define S_POSIX 1 +#define S_LINUX 2 #define S_OTHER 3 /* Second set, not necessarily OS-dependant */ -#define S_ALT1 1 -#define S_ALT2 2 -#define S_ALT3 3 +#define S_ALT1 1 +#define S_ALT2 2 +#define S_ALT3 3 /** Insert desired selectors here **/ -//example: +// example: //#define SEL_TIMEOUT S_OTHER //#define SEL_TIMEOUT S_LINUX //#define SEL_TTYBAUD S_ALT3 @@ -81,17 +79,16 @@ extern "C" { /* Default selectors: anything still undefined is set to S_AUTO which means "force nothing", i.e. "use most appropriate implementation". */ #ifndef SEL_TIMEOUT -#define SEL_TIMEOUT S_AUTO +# define SEL_TIMEOUT S_AUTO #endif #ifndef SEL_TTYOPEN -#define SEL_TTYOPEN S_AUTO +# define SEL_TTYOPEN S_AUTO #endif #ifndef SEL_TTYBAUD -#define SEL_TTYBAUD S_AUTO +# define SEL_TTYBAUD S_AUTO #endif /****** ******/ - /* There are two possible definitions for "struct termios". One is found in provided by glibc; the other is in provided @@ -99,63 +96,62 @@ extern "C" { */ /** FUGLY HACKS BELOW **/ -#if defined(__linux__) && (SEL_TTYBAUD==S_ALT1 || SEL_TTYBAUD==S_AUTO) - #define USE_TERMIOS2 +#if defined(__linux__) && (SEL_TTYBAUD == S_ALT1 || SEL_TTYBAUD == S_AUTO) +# define USE_TERMIOS2 #endif #ifdef USE_TERMIOS2 - #include //including causes duplicate def errors - - /* Ugliness necessary because : - 0- , or at least is needed for BOTHER and struct termios2 - 1- ioctl() is provided by glibc, and defined in - 2- (included through sys/ioctl.h -> bits/ioctls.h -> asm/ioctls.h) is needed for TCSETS2 - 3- defines winsize and some other junk covered by bits/ioctl-types; - 3b- is included by ! - - Could we someday have a sane way of setting integer baud rates ? pfah. - */ - extern int cfsetispeed(struct termios *__termios_p, speed_t __speed); - extern int cfsetospeed(struct termios *__termios_p, speed_t __speed); +# include //including causes duplicate def errors + +/* Ugliness necessary because : + 0- , or at least is needed for BOTHER and struct termios2 + 1- ioctl() is provided by glibc, and defined in + 2- (included through sys/ioctl.h -> bits/ioctls.h -> asm/ioctls.h) is +needed for TCSETS2 3- defines winsize and some other junk covered by +bits/ioctl-types; 3b- is included by ! + +Could we someday have a sane way of setting integer baud rates ? pfah. + */ +extern int cfsetispeed(struct termios *__termios_p, speed_t __speed); +extern int cfsetospeed(struct termios *__termios_p, speed_t __speed); #else - #include //has speed_t, tcsetattr, struct termios, cfset*speed, etc -#endif // USE_TERMIOS2 +# include //has speed_t, tcsetattr, struct termios, cfset*speed, etc +#endif // USE_TERMIOS2 /** END OF FUGLINESS **/ #include #if defined(_POSIX_TIMERS) - #include +# include #endif #if defined(__linux__) - #include - #include /* For Linux-specific struct serial_struct */ +# include +# include /* For Linux-specific struct serial_struct */ #endif #include "diag_tty.h" #define DL0D_INVALIDHANDLE -1 - -//struct tty_int : internal data, one per L0 struct +// struct tty_int : internal data, one per L0 struct struct unix_tty_int { - char *name; /* port name */ - int fd; /* File descriptor */ + char *name; /* port name */ + int fd; /* File descriptor */ #if defined(__linux__) - //struct serial_struct : only used with TIOCGSERIAL + TIOCSSERIAL ioctls, + // struct serial_struct : only used with TIOCGSERIAL + TIOCSSERIAL ioctls, // which are not always available. Hence this flag: - int tioc_works; //indicate if TIOCGSERIAL + TIOCSSERIAL work - //TODO : expand to a more general "detected tty capabilities" set of flags. + int tioc_works; // indicate if TIOCGSERIAL + TIOCSSERIAL work + // TODO : expand to a more general "detected tty capabilities" set of flags. /* For recording state before/while/after messing with the interface: */ - struct serial_struct ss_orig; //original backup - struct serial_struct ss_cur; //current state + struct serial_struct ss_orig; // original backup + struct serial_struct ss_cur; // current state #endif - //backup & current termios structs + // backup & current termios structs struct termios st_orig; struct termios st_cur; #ifdef USE_TERMIOS2 @@ -163,18 +159,19 @@ struct unix_tty_int { struct termios2 st2_orig; #endif - //flags backup (ioctl TIOCMGET, TIOCMSET) + // flags backup (ioctl TIOCMGET, TIOCMSET) int modemflags; #if defined(_POSIX_TIMERS) - timer_t timerid; //Used for read() and write() timeouts - volatile sig_atomic_t pt_expired; //flag timeout expiry + timer_t timerid; // Used for read() and write() timeouts + volatile sig_atomic_t pt_expired; // flag timeout expiry #endif - unsigned long int byte_write_timeout_us; //single byte write timeout in microseconds + unsigned long int byte_write_timeout_us; // single byte write timeout in + // microseconds }; #if defined(__cplusplus) } -#endif +# endif #endif /*_DIAG_TTY_UNIX_H_ */ diff --git a/scantool/diag_tty_win.c b/scantool/diag_tty_win.c index 596cc42e..602802b5 100644 --- a/scantool/diag_tty_win.c +++ b/scantool/diag_tty_win.c @@ -17,17 +17,18 @@ #include extern LARGE_INTEGER perfo_freq; -extern float pf_conv; //these two are defined in diag_os +extern float pf_conv; // these two are defined in diag_os -//struct tty_int : internal data, one per L0 struct +// struct tty_int : internal data, one per L0 struct struct tty_int { - char *name; //port name, alloc'd + char *name; // port name, alloc'd HANDLE fd; DCB dcb; }; -//diag_tty_open : open specified port for L0 -ttyp *diag_tty_open(const char *portname) { +// diag_tty_open : open specified port for L0 +ttyp * +diag_tty_open(const char *portname) { int rv; struct tty_int *wti; size_t n = strlen(portname) + 1; @@ -35,103 +36,110 @@ ttyp *diag_tty_open(const char *portname) { assert(portname); - if ((rv=diag_calloc(&wti,1))) { + if ((rv = diag_calloc(&wti, 1))) { return diag_pseterr(rv); } wti->fd = INVALID_HANDLE_VALUE; - //allocate space for portname name - if ((rv=diag_malloc(&wti->name, n))) { + // allocate space for portname name + if ((rv = diag_malloc(&wti->name, n))) { free(wti); return diag_pseterr(rv); } - //Now, in case of errors we can call diag_tty_close() on wti since its members are alloc'ed + // Now, in case of errors we can call diag_tty_close() on wti since its members are + // alloc'ed strncpy(wti->name, portname, n); - wti->fd=CreateFile(portname, GENERIC_READ | GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, + wti->fd = CreateFile( + portname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL); - //File hande is created as non-overlapped. This may change eventually. + // File hande is created as non-overlapped. This may change eventually. if (wti->fd != INVALID_HANDLE_VALUE) { - if (diag_l0_debug & DIAG_DEBUG_OPEN) - fprintf(stderr, FLFMT "Device %s opened, fd %p\n", - FL, wti->name, wti->fd); + if (diag_l0_debug_load() & DIAG_DEBUG_OPEN) + fprintf(stderr, FLFMT "Device %s opened, fd %p\n", FL, wti->name, + wti->fd); } else { + fprintf(stderr, FLFMT "Open of device interface \"%s\" failed: %s\n", FL, + wti->name, diag_os_geterr(0)); fprintf(stderr, - FLFMT "Open of device interface \"%s\" failed: %s\n", - FL, wti->name, diag_os_geterr(0)); - fprintf(stderr, FLFMT - "(Make sure the device specified corresponds to the\n", FL ); - fprintf(stderr, - FLFMT "serial device your interface is connected to.\n", FL); + FLFMT "(Make sure the device specified corresponds to the\n", FL); + fprintf(stderr, FLFMT "serial device your interface is connected to.\n", + FL); diag_tty_close(wti); return diag_pseterr(DIAG_ERR_GENERAL); } - //purge & abort everything. - PurgeComm(wti->fd,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); + // purge & abort everything. + PurgeComm(wti->fd, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); - //as opposed to the unix diag_tty.c ; this one doesn't save previous commstate. The next program to use the COM port - //will need to deal with it... + // as opposed to the unix diag_tty.c ; this one doesn't save previous commstate. + // The next program to use the COM port will need to deal with it... - //We will load the DCB with the current comm state. This way we only need to call GetCommState once during a session - //and the DCB should contain coherent initial values - if (! GetCommState(wti->fd, &wti->dcb)) { - fprintf(stderr, FLFMT "Could not get comm state: %s\n",FL, diag_os_geterr(0)); + // We will load the DCB with the current comm state. This way we only need to call + // GetCommState once during a session and the DCB should contain coherent initial + // values + if (!GetCommState(wti->fd, &wti->dcb)) { + fprintf(stderr, FLFMT "Could not get comm state: %s\n", FL, + diag_os_geterr(0)); diag_tty_close(wti); return diag_pseterr(DIAG_ERR_GENERAL); } - //Finally set COMMTIMEOUTS to reasonable values (all in ms) ? - devtimeouts.ReadIntervalTimeout=30; //i.e. more than 30ms between received bytes - devtimeouts.ReadTotalTimeoutMultiplier=5; //timeout per requested byte - devtimeouts.ReadTotalTimeoutConstant=20; // (constant + multiplier*numbytes) = total timeout on read(buf, numbytes) - devtimeouts.WriteTotalTimeoutMultiplier=0; //probably useless as all flow control will be disabled ?? - devtimeouts.WriteTotalTimeoutConstant=0; - if (! SetCommTimeouts(wti->fd,&devtimeouts)) { - fprintf(stderr, FLFMT "Could not set comm timeouts: %s\n",FL, diag_os_geterr(0)); + // Finally set COMMTIMEOUTS to reasonable values (all in ms) ? + devtimeouts.ReadIntervalTimeout = 30; // i.e. more than 30ms between received bytes + devtimeouts.ReadTotalTimeoutMultiplier = 5; // timeout per requested byte + devtimeouts.ReadTotalTimeoutConstant = 20; // (constant + multiplier*numbytes) = + // total timeout on read(buf, numbytes) + devtimeouts.WriteTotalTimeoutMultiplier = 0; // probably useless as all flow + // control will be disabled ?? + devtimeouts.WriteTotalTimeoutConstant = 0; + if (!SetCommTimeouts(wti->fd, &devtimeouts)) { + fprintf(stderr, FLFMT "Could not set comm timeouts: %s\n", FL, + diag_os_geterr(0)); diag_tty_close(wti); return diag_pseterr(DIAG_ERR_GENERAL); } return wti; -} //diag_tty_open +} // diag_tty_open /* Close up the TTY and restore. */ -void diag_tty_close(ttyp *ttyh) { +void +diag_tty_close(ttyp *ttyh) { struct tty_int *wti = ttyh; - if (!wti) return; + if (!wti) + return; if (wti->name) { free(wti->name); } if (wti->fd != INVALID_HANDLE_VALUE) { - PurgeComm(wti->fd,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); + PurgeComm(wti->fd, + PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); CloseHandle(wti->fd); - if (diag_l0_debug & DIAG_DEBUG_CLOSE) - fprintf(stderr, FLFMT "diag_tty_close : closing fd %p\n", FL, wti->fd); + if (diag_l0_debug_load() & DIAG_DEBUG_CLOSE) + fprintf(stderr, FLFMT "diag_tty_close : closing fd %p\n", FL, + wti->fd); } free(wti); return; -} //diag_tty_close - +} // diag_tty_close /* * Set speed/parity etc of tty with settings in pset * ret 0 if ok */ int -diag_tty_setup(ttyp *ttyh, - const struct diag_serial_settings *pset) { - HANDLE devhandle; //just to clarify code +diag_tty_setup(ttyp *ttyh, const struct diag_serial_settings *pset) { + HANDLE devhandle; // just to clarify code struct tty_int *wti = ttyh; DCB *devstate; COMMPROP supportedprops; @@ -145,157 +153,162 @@ diag_tty_setup(ttyp *ttyh, return diag_iseterr(DIAG_ERR_GENERAL); } - //optional : verify if device supports the requested settings. Testing required to see if USB->serial bridges support this ! - //i.e. some l0 devices try to set 5bps which isn't supported on some devices. - //For now let's just check if it supports custom baud rates. This check should be added to diag_tty_open where - //it would set appropriate flags to allow _l0 devices to adapt their functionality. - if (! GetCommProperties(devhandle,&supportedprops)) { - fprintf(stderr, FLFMT "could not getcommproperties: %s\n",FL, diag_os_geterr(0)); + // optional : verify if device supports the requested settings. Testing required to + // see if USB->serial bridges support this ! i.e. some l0 devices try to set 5bps + // which isn't supported on some devices. For now let's just check if it supports + // custom baud rates. This check should be added to diag_tty_open where it would + // set appropriate flags to allow _l0 devices to adapt their functionality. + if (!GetCommProperties(devhandle, &supportedprops)) { + fprintf(stderr, FLFMT "could not getcommproperties: %s\n", FL, + diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } - //simple test : only check if custom baud rates are supported, but don't abort if they aren't. Just notify user. - if ( !(supportedprops.dwMaxBaud & BAUD_USER)) - fprintf(stderr, FLFMT "warning : device does not support custom baud rates !\n", FL); - - + // simple test : only check if custom baud rates are supported, but don't abort if + // they aren't. Just notify user. + if (!(supportedprops.dwMaxBaud & BAUD_USER)) + fprintf(stderr, + FLFMT "warning : device does not support custom baud rates !\n", + FL); - if (diag_l0_debug & DIAG_DEBUG_IOCTL) { - fprintf(stderr, FLFMT "dev %p; %dbps %d,%d,%d \n", - FL, (void *)devhandle, pset->speed, - pset->databits, pset->stopbits, pset->parflag); + if (diag_l0_debug_load() & DIAG_DEBUG_IOCTL) { + fprintf(stderr, FLFMT "dev %p; %dbps %d,%d,%d \n", FL, (void *)devhandle, + pset->speed, pset->databits, pset->stopbits, pset->parflag); } /* * Now load the DCB with the parameters requested. */ - // the DCB (devstate) has been loaded with initial values in diag_tty_open so it should already coherent. + // the DCB (devstate) has been loaded with initial values in diag_tty_open so it + // should already coherent. devstate->BaudRate = pset->speed; - devstate->fBinary=1; // always binary mode. + devstate->fBinary = 1; // always binary mode. switch (pset->parflag) { - case diag_par_n: - //no parity : disable parity in the DCB - devstate->fParity=0; - devstate->Parity=NOPARITY; - break; - case diag_par_e: - devstate->fParity=1; - devstate->Parity=EVENPARITY; - break; - case diag_par_o: - devstate->fParity=1; - devstate->Parity=ODDPARITY; - break; - default: - fprintf(stderr, - FLFMT "bad parity setting used !\n", FL); - return diag_iseterr(DIAG_ERR_GENERAL); - break; - } - devstate->fOutxCtsFlow=0; - devstate->fOutxDsrFlow=0; //disable output flow control - devstate->fDtrControl=DTR_CONTROL_DISABLE; //XXX allows to permanently set the DTR line ! - devstate->fDsrSensitivity=0; //pay no attention to DSR for receiving - devstate->fTXContinueOnXoff=1; //probably irrelevant ? - devstate->fOutX=0; //disable Xon/Xoff tx flow ctl - devstate->fInX=0; //disable XonXoff rx flow ctl - devstate->fErrorChar=0; //do not replace data with bad parity - devstate->fNull=0; // do not discard null bytes ! on rx - devstate->fRtsControl=RTS_CONTROL_DISABLE; //XXX allows to set the RTS line! - devstate->fAbortOnError=0; //do not abort transfers on error ? - devstate->wReserved=0; - devstate->ByteSize=pset->databits; //bits per byte + case diag_par_n: + // no parity : disable parity in the DCB + devstate->fParity = 0; + devstate->Parity = NOPARITY; + break; + case diag_par_e: + devstate->fParity = 1; + devstate->Parity = EVENPARITY; + break; + case diag_par_o: + devstate->fParity = 1; + devstate->Parity = ODDPARITY; + break; + default: + fprintf(stderr, FLFMT "bad parity setting used !\n", FL); + return diag_iseterr(DIAG_ERR_GENERAL); + break; + } + devstate->fOutxCtsFlow = 0; + devstate->fOutxDsrFlow = 0; // disable output flow control + devstate->fDtrControl = DTR_CONTROL_DISABLE; // XXX allows to permanently set the + // DTR line ! + devstate->fDsrSensitivity = 0; // pay no attention to DSR for receiving + devstate->fTXContinueOnXoff = 1; // probably irrelevant ? + devstate->fOutX = 0; // disable Xon/Xoff tx flow ctl + devstate->fInX = 0; // disable XonXoff rx flow ctl + devstate->fErrorChar = 0; // do not replace data with bad parity + devstate->fNull = 0; // do not discard null bytes ! on rx + devstate->fRtsControl = RTS_CONTROL_DISABLE; // XXX allows to set the RTS line! + devstate->fAbortOnError = 0; // do not abort transfers on error ? + devstate->wReserved = 0; + devstate->ByteSize = pset->databits; // bits per byte switch (pset->stopbits) { - case diag_stopbits_1: - devstate->StopBits=ONESTOPBIT; - break; - case diag_stopbits_2: - devstate->StopBits=TWOSTOPBITS; - break; - default: - fprintf(stderr, FLFMT "bad stopbit setting used!)\n", FL); - return diag_iseterr(DIAG_ERR_GENERAL); - break; + case diag_stopbits_1: + devstate->StopBits = ONESTOPBIT; + break; + case diag_stopbits_2: + devstate->StopBits = TWOSTOPBITS; + break; + default: + fprintf(stderr, FLFMT "bad stopbit setting used!)\n", FL); + return diag_iseterr(DIAG_ERR_GENERAL); + break; } // DCB in devstate is now filled. - if (! SetCommState(devhandle, devstate)) { - fprintf(stderr, FLFMT "Could not SetCommState: %s\n",FL, diag_os_geterr(0)); + if (!SetCommState(devhandle, devstate)) { + fprintf(stderr, FLFMT "Could not SetCommState: %s\n", FL, + diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } - //to be really thorough we do another GetCommState and check that the speed was set properly. - //This *may* help to detect if the serial port supports non-standard baudrates (5bps being - //particularly problematic with USB->serial converters) - //I see no particular reason to check all the other fields though. + // to be really thorough we do another GetCommState and check that the speed was + // set properly. This *may* help to detect if the serial port supports non-standard + // baudrates (5bps being particularly problematic with USB->serial converters) I + // see no particular reason to check all the other fields though. - if (! GetCommState(devhandle, &verif_dcb)) { - fprintf(stderr, FLFMT "Could not verify with GetCommState: %s\n", FL, diag_os_geterr(0)); + if (!GetCommState(devhandle, &verif_dcb)) { + fprintf(stderr, FLFMT "Could not verify with GetCommState: %s\n", FL, + diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } if (verif_dcb.BaudRate != pset->speed) { - fprintf(stderr, FLFMT "SetCommState failed : speed is currently %u\n", FL, (unsigned int) verif_dcb.BaudRate); + fprintf(stderr, FLFMT "SetCommState failed : speed is currently %u\n", FL, + (unsigned int)verif_dcb.BaudRate); return diag_iseterr(DIAG_ERR_GENERAL); } return 0; -} //diag_tty_setup +} // diag_tty_setup /* * Set/Clear DTR and RTS lines, as specified * on Win32 this can easily be done by calling EscapeCommFunction twice. * This takes around ~15-20us to do; probably with ~10 us skew between setting RTS and DTR. - * If it proves to be a problem, it's possible to change both RTS and DTR at once by updating - * the DCB and calling SetCommState. That call would take around 30-40us. - * Note : passing 1 in dtr or rts means "set DTR/RTS", i.e. positive voltage. - * ret 0 if ok + * If it proves to be a problem, it's possible to change both RTS and DTR at once by + * updating the DCB and calling SetCommState. That call would take around 30-40us. Note : + * passing 1 in dtr or rts means "set DTR/RTS", i.e. positive voltage. ret 0 if ok */ int diag_tty_control(ttyp *ttyh, unsigned int dtr, unsigned int rts) { unsigned int escapefunc; struct tty_int *wti = ttyh; - if (wti->fd == INVALID_HANDLE_VALUE) { fprintf(stderr, FLFMT "Error. Is the port open ?\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } if (dtr) - escapefunc=SETDTR; + escapefunc = SETDTR; else - escapefunc=CLRDTR; + escapefunc = CLRDTR; - if (! EscapeCommFunction(wti->fd,escapefunc)) { + if (!EscapeCommFunction(wti->fd, escapefunc)) { fprintf(stderr, FLFMT "Could not change DTR: %s\n", FL, diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } if (rts) - escapefunc=SETRTS; + escapefunc = SETRTS; else - escapefunc=CLRRTS; + escapefunc = CLRRTS; - if (! EscapeCommFunction(wti->fd,escapefunc)) { + if (!EscapeCommFunction(wti->fd, escapefunc)) { fprintf(stderr, FLFMT "Could not change RTS: %s\n", FL, diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } return 0; -} //diag_tty_control +} // diag_tty_control - -//diag_tty_write : return # of bytes or <0 if error? -//this is an intimidating function to design. -//test #2 : non-overlapped write (i.e. blocking AKA synchronous). +// diag_tty_write : return # of bytes or <0 if error? +// this is an intimidating function to design. +// test #2 : non-overlapped write (i.e. blocking AKA synchronous). // -//flush buffers before returning; we could also SetCommMask -//to wait for "EV_TXEMPTY" which would give a better idea -//of when the data has been sent. +// flush buffers before returning; we could also SetCommMask +// to wait for "EV_TXEMPTY" which would give a better idea +// of when the data has been sent. -ssize_t diag_tty_write(ttyp *ttyh, const void *buf, const size_t count) { +ssize_t +diag_tty_write(ttyp *ttyh, const void *buf, const size_t count) { DWORD byteswritten; OVERLAPPED *pOverlap; struct tty_int *wti = ttyh; - pOverlap=NULL; //note : if overlap is eventually enabled, the CreateFile flags should be adjusted + pOverlap = NULL; // note : if overlap is eventually enabled, the CreateFile flags + // should be adjusted if (wti->fd == INVALID_HANDLE_VALUE) { fprintf(stderr, FLFMT "Error. Is the port open ?\n", FL); @@ -305,42 +318,44 @@ ssize_t diag_tty_write(ttyp *ttyh, const void *buf, const size_t count) { if (count <= 0) return diag_iseterr(DIAG_ERR_BADLEN); - if (! WriteFile(wti->fd, buf, count, &byteswritten, pOverlap)) { - fprintf(stderr, FLFMT "WriteFile error:%s. %u bytes written, %u requested\n", FL, diag_os_geterr(0), (unsigned int) byteswritten, (unsigned) count); + if (!WriteFile(wti->fd, buf, count, &byteswritten, pOverlap)) { + fprintf(stderr, + FLFMT "WriteFile error:%s. %u bytes written, %u requested\n", FL, + diag_os_geterr(0), (unsigned int)byteswritten, (unsigned)count); return diag_iseterr(DIAG_ERR_GENERAL); } if (!FlushFileBuffers(wti->fd)) { - fprintf(stderr, FLFMT "tty_write : could not flush buffers, %s\n", FL, diag_os_geterr(0)); + fprintf(stderr, FLFMT "tty_write : could not flush buffers, %s\n", FL, + diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } return byteswritten; -} //diag_tty_write - +} // diag_tty_write // diag_tty_read -//attempt to read (count) bytes until (timeout) passes. -//calling with timeout==0 makes ReadFile return immediately with or without any data. -//This one returns # of bytes read (if any) -//This is non-overlapped for now i.e. blocking. -//timeouts and incomplete data are not handled properly. This is alpha... -//From the API docs : +// attempt to read (count) bytes until (timeout) passes. +// calling with timeout==0 makes ReadFile return immediately with or without any data. +// This one returns # of bytes read (if any) +// This is non-overlapped for now i.e. blocking. +// timeouts and incomplete data are not handled properly. This is alpha... +// From the API docs : // ReadFile returns when the number of bytes requested has been read, or an error occurs. - ssize_t diag_tty_read(ttyp *ttyh, void *buf, size_t count, unsigned int timeout) { DWORD bytesread; - ssize_t rv=DIAG_ERR_TIMEOUT; + ssize_t rv = DIAG_ERR_TIMEOUT; OVERLAPPED *pOverlap; struct tty_int *wti = ttyh; - pOverlap=NULL; + pOverlap = NULL; COMMTIMEOUTS devtimeouts; - if ((count <= 0) || (timeout <= 0)) return DIAG_ERR_BADLEN; + if ((count <= 0) || (timeout <= 0)) + return DIAG_ERR_BADLEN; - if (diag_l0_debug & DIAG_DEBUG_READ) { + if (diag_l0_debug_load() & DIAG_DEBUG_READ) { fprintf(stderr, FLFMT "tty_read: ttyh=%p, fd=%p, len=%zu, t=%u\n", FL, - (void *)wti, (void *)wti->fd, count, timeout); + (void *)wti, (void *)wti->fd, count, timeout); } if (wti->fd == INVALID_HANDLE_VALUE) { @@ -348,62 +363,64 @@ diag_tty_read(ttyp *ttyh, void *buf, size_t count, unsigned int timeout) { return diag_iseterr(DIAG_ERR_GENERAL); } -// GetCommTimeouts(wti->, &devtimeouts); //get current timeouts - //and modify them - devtimeouts.ReadIntervalTimeout= timeout ? 0:MAXDWORD; //disabled unless timeout was 0. - devtimeouts.ReadTotalTimeoutMultiplier=0; //timeout per requested byte - devtimeouts.ReadTotalTimeoutConstant=timeout; // (tconst + mult*numbytes) = total timeout on read - devtimeouts.WriteTotalTimeoutMultiplier=0; //probably useless as all flow control will be disabled ?? - devtimeouts.WriteTotalTimeoutConstant=0; - if (! SetCommTimeouts(wti->fd, &devtimeouts)) { - fprintf(stderr, FLFMT "Could not set comm timeouts: %s\n",FL, diag_os_geterr(0)); + // GetCommTimeouts(wti->, &devtimeouts); //get current timeouts + // and modify them + devtimeouts.ReadIntervalTimeout = timeout ? 0 : MAXDWORD; // disabled unless + // timeout was 0. + devtimeouts.ReadTotalTimeoutMultiplier = 0; // timeout per requested byte + devtimeouts.ReadTotalTimeoutConstant = timeout; // (tconst + mult*numbytes) = total + // timeout on read + devtimeouts.WriteTotalTimeoutMultiplier = 0; // probably useless as all flow + // control will be disabled ?? + devtimeouts.WriteTotalTimeoutConstant = 0; + if (!SetCommTimeouts(wti->fd, &devtimeouts)) { + fprintf(stderr, FLFMT "Could not set comm timeouts: %s\n", FL, + diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } - if (! ReadFile(wti->fd, buf, count, &bytesread, pOverlap)) { - fprintf(stderr, FLFMT "ReadFile error: %s\n",FL, diag_os_geterr(0)); + if (!ReadFile(wti->fd, buf, count, &bytesread, pOverlap)) { + fprintf(stderr, FLFMT "ReadFile error: %s\n", FL, diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } if (bytesread > 0) - rv=bytesread; + rv = bytesread; return rv; - } - - /* * flush input buffer and display some of the discarded data * ret 0 if ok * */ -int diag_tty_iflush(ttyp *ttyh) { +int +diag_tty_iflush(ttyp *ttyh) { uint8_t buf[MAXRBUF]; int rv; struct tty_int *wti = ttyh; /* Read any old data hanging about on the port */ rv = diag_tty_read(wti, buf, sizeof(buf), IFLUSH_TIMEOUT); - if ((rv > 0) && (diag_l0_debug & DIAG_DEBUG_DATA)) { - fprintf(stderr, FLFMT "tty_iflush: >=%d junk bytes discarded: 0x%X...\n", FL, rv, buf[0]); - // diag_data_dump(stderr, (void *) buf, (size_t) rv); //this could take a long time. - // fprintf(stderr,"\n"); + if ((rv > 0) && (diag_l0_debug_load() & DIAG_DEBUG_DATA)) { + fprintf(stderr, FLFMT "tty_iflush: >=%d junk bytes discarded: 0x%X...\n", + FL, rv, buf[0]); + // diag_data_dump(stderr, (void *) buf, (size_t) rv); //this could take a + // long time. fprintf(stderr,"\n"); } PurgeComm(wti->fd, PURGE_RXABORT | PURGE_RXCLEAR); return 0; } - - // diag_tty_break #1 : use Set / ClearCommBreak // and return as soon as break is cleared. // ret 0 if ok -int diag_tty_break(ttyp *ttyh, const unsigned int ms) { - LARGE_INTEGER qpc1, qpc2; //for timing verification - long real_t; //"real" duration +int +diag_tty_break(ttyp *ttyh, const unsigned int ms) { + LARGE_INTEGER qpc1, qpc2; // for timing verification + long real_t; //"real" duration struct tty_int *wti = ttyh; - int errval=0; + int errval = 0; if (wti->fd == INVALID_HANDLE_VALUE) { fprintf(stderr, FLFMT "Error. Is the port open ?\n", FL); @@ -416,17 +433,19 @@ int diag_tty_break(ttyp *ttyh, const unsigned int ms) { QueryPerformanceCounter(&qpc1); errval = !SetCommBreak(wti->fd); QueryPerformanceCounter(&qpc2); - //that call can take quite a while (6ms !!) on some setups (win7 + CH340 USB-Serial). - //It's still impossible to know (from here) when exactly TXD goes low (beginning or end of the call) - real_t=(long) (pf_conv * (qpc2.QuadPart-qpc1.QuadPart)) / 1000L; - real_t = (long) ms - real_t; //time remaining - if (real_t <= 0) real_t = 0; - diag_os_millisleep((unsigned int ) real_t); + // that call can take quite a while (6ms !!) on some setups (win7 + CH340 + // USB-Serial). It's still impossible to know (from here) when exactly TXD goes low + // (beginning or end of the call) + real_t = (long)(pf_conv * (qpc2.QuadPart - qpc1.QuadPart)) / 1000L; + real_t = (long)ms - real_t; // time remaining + if (real_t <= 0) + real_t = 0; + diag_os_millisleep((unsigned int)real_t); errval |= !ClearCommBreak(wti->fd); if (errval) { - //if either of the calls failed + // if either of the calls failed fprintf(stderr, FLFMT "tty_break could not set/clear break!\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } @@ -434,28 +453,27 @@ int diag_tty_break(ttyp *ttyh, const unsigned int ms) { return 0; } - /* - * diag_tty_fastbreak: send 0x00 at 360bps => fixed 25ms break; return [ms] after starting break. - * This is for ISO14230 fast init : typically diag_tty_fastbreak(tty_int, 50) - * It assumes the interface is half-duplex. - * Ret 0 if ok + * diag_tty_fastbreak: send 0x00 at 360bps => fixed 25ms break; return [ms] after starting + * break. This is for ISO14230 fast init : typically diag_tty_fastbreak(tty_int, 50) It + * assumes the interface is half-duplex. Ret 0 if ok */ -int diag_tty_fastbreak(ttyp *ttyh, const unsigned int ms) { - HANDLE dh; //just to clarify code +int +diag_tty_fastbreak(ttyp *ttyh, const unsigned int ms) { + HANDLE dh; // just to clarify code struct tty_int *wti = ttyh; - DCB tempDCB; //for sabotaging the settings just to do the break + DCB tempDCB; // for sabotaging the settings just to do the break DCB origDCB; - LARGE_INTEGER qpc1, qpc2, qpc3; //to time the break period - LONGLONG timediff; //64bit delta - long int tremain,counts, break_error; + LARGE_INTEGER qpc1, qpc2, qpc3; // to time the break period + LONGLONG timediff; // 64bit delta + long int tremain, counts, break_error; uint8_t cbuf; int xferd; DWORD byteswritten; dh = wti->fd; - if (ms<25) //very funny + if (ms < 25) // very funny return diag_iseterr(DIAG_ERR_TIMEOUT); if (dh == INVALID_HANDLE_VALUE) { @@ -464,29 +482,29 @@ int diag_tty_fastbreak(ttyp *ttyh, const unsigned int ms) { } GetCommState(dh, &origDCB); - GetCommState(dh, &tempDCB); //ugly, but a memcpy would be worse + GetCommState(dh, &tempDCB); // ugly, but a memcpy would be worse - tempDCB.BaudRate=360; - tempDCB.ByteSize=8; - tempDCB.fParity=0; - tempDCB.Parity=NOPARITY; - tempDCB.StopBits=ONESTOPBIT; + tempDCB.BaudRate = 360; + tempDCB.ByteSize = 8; + tempDCB.fParity = 0; + tempDCB.Parity = NOPARITY; + tempDCB.StopBits = ONESTOPBIT; - if (! SetCommState(dh, &tempDCB)) { + if (!SetCommState(dh, &tempDCB)) { fprintf(stderr, FLFMT "SetCommState error\n", FL); return diag_iseterr(DIAG_ERR_GENERAL); } /* Send a 0x00 byte message */ - if (! WriteFile(dh, "\0", 1, &byteswritten, NULL)) { + if (!WriteFile(dh, "\0", 1, &byteswritten, NULL)) { fprintf(stderr, FLFMT "WriteFile error:%s\n", FL, diag_os_geterr(0)); SetCommState(dh, &origDCB); return diag_iseterr(DIAG_ERR_GENERAL); } - //get approx starting time. I think this is the closest we can - //get to the actual time the byte gets sent since we call FFB - //right after. + // get approx starting time. I think this is the closest we can + // get to the actual time the byte gets sent since we call FFB + // right after. QueryPerformanceCounter(&qpc1); if (!FlushFileBuffers(dh)) { @@ -495,21 +513,21 @@ int diag_tty_fastbreak(ttyp *ttyh, const unsigned int ms) { return diag_iseterr(DIAG_ERR_GENERAL); } - /* * And read back the single byte echo, which shows TX completes - */ + */ xferd = diag_tty_read(wti, &cbuf, 1, ms + 20); - //we'll usually have a few ms left to wait; we'll use this - //to restore the port settings + // we'll usually have a few ms left to wait; we'll use this + // to restore the port settings - if (! SetCommState(dh, &origDCB)) { - fprintf(stderr, FLFMT "tty_fastbreak: could not restore setting: %s\n", FL, diag_os_geterr(0)); + if (!SetCommState(dh, &origDCB)) { + fprintf(stderr, FLFMT "tty_fastbreak: could not restore setting: %s\n", FL, + diag_os_geterr(0)); return diag_iseterr(DIAG_ERR_GENERAL); } - //Not getting the echo byte doesn't mean fastbreak has necessarily + // Not getting the echo byte doesn't mean fastbreak has necessarily // failed. But we really should be getting an echo back... if (xferd < 0) return diag_iseterr(xferd); @@ -519,72 +537,89 @@ int diag_tty_fastbreak(ttyp *ttyh, const unsigned int ms) { return diag_iseterr(DIAG_ERR_GENERAL); } - - QueryPerformanceCounter(&qpc2); //get current time, - timediff=qpc2.QuadPart-qpc1.QuadPart; //elapsed counts since diag_tty_write - counts=(ms*perfo_freq.QuadPart)/1000; //total # of counts for requested tWUP - tremain=counts-timediff; //counts remaining - if (tremain<=0) + QueryPerformanceCounter(&qpc2); // get current time, + timediff = qpc2.QuadPart - qpc1.QuadPart; // elapsed counts since diag_tty_write + counts = (ms * perfo_freq.QuadPart) / 1000; // total # of counts for requested tWUP + tremain = counts - timediff; // counts remaining + if (tremain <= 0) return 0; - tremain = ((LONGLONG) tremain*1000)/perfo_freq.QuadPart; //convert to ms; imprecise but that should be OK. - diag_os_millisleep((unsigned int) tremain); + tremain = ((LONGLONG)tremain * 1000) / perfo_freq.QuadPart; // convert to ms; + // imprecise but that + // should be OK. + diag_os_millisleep((unsigned int)tremain); QueryPerformanceCounter(&qpc3); - timediff=qpc3.QuadPart-qpc1.QuadPart; //total cycle time. - break_error= (long) timediff - counts; //real - requested - break_error= (long) (break_error * pf_conv); //convert to us ! + timediff = qpc3.QuadPart - qpc1.QuadPart; // total cycle time. + break_error = (long)timediff - counts; // real - requested + break_error = (long)(break_error * pf_conv); // convert to us ! if (break_error > 1000 || break_error < -1000) - fprintf(stderr, FLFMT "tty_fastbreak: tWUP out of spec by %ldus!\n", FL, break_error); - + fprintf(stderr, FLFMT "tty_fastbreak: tWUP out of spec by %ldus!\n", FL, + break_error); return 0; -} //diag_tty_fastbreak +} // diag_tty_fastbreak /* Find valid serial ports. * Adapted from FreeSSM : * https://github.com/Comer352L/FreeSSM */ -char **diag_tty_getportlist(int *numports) { - HKEY hKey; // handle to registry key - DWORD index = 0; // index registry-key: unsigned int (32bit) +char ** +diag_tty_getportlist(int *numports) { + HKEY hKey; // handle to registry key + DWORD index = 0; // index registry-key: unsigned int (32bit) char ValueName[256] = ""; - unsigned long szValueName = 256; // variable that specifies the size (in characters, including the terminating null char) of the buffer pointed to by the "ValueName" parameter. - unsigned char Data[256] = ""; // buffer that receives the data for the value entry. This parameter can be NULL if the data is not required - unsigned long szData = 256; // variable that specifies the size, in bytes, of the buffer pointed to by the lpData parameter. + unsigned long szValueName = 256; // variable that specifies the size (in + // characters, including the terminating null + // char) of the buffer pointed to by the + // "ValueName" parameter. + unsigned char Data[256] = ""; // buffer that receives the data for the value entry. + // This parameter can be NULL if the data is not + // required + unsigned long szData = 256; // variable that specifies the size, in bytes, of the + // buffer pointed to by the lpData parameter. long cv; HANDLE hCom_t = NULL; - char **portlist=NULL; - int elems=0; //temp number of ports found + char **portlist = NULL; + int elems = 0; // temp number of ports found assert(numports != NULL); *numports = 0; // OPEN REGISTRY-KEY AND BROWSE ENTRYS: - cv = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_READ, &hKey); + cv = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, + KEY_READ, &hKey); if (cv == ERROR_SUCCESS) { - while ((RegEnumValueA(hKey, index, ValueName, &szValueName, NULL, NULL,Data,&szData)) == ERROR_SUCCESS) { - if (!strncmp((char *)Data,"COM",3)) { + while ((RegEnumValueA(hKey, index, ValueName, &szValueName, NULL, NULL, + Data, &szData)) == ERROR_SUCCESS) { + if (!strncmp((char *)Data, "COM", 3)) { // CHECK IF PORT IS AVAILABLE (not in use): - char NTdevName[30] = "\\\\.\\"; // => "\\.\" - strncpy(NTdevName+4, (char *)Data, 25); - /* NOTE: MS-DOS device names ("COMx") are not reliable if x is > 9 !!! - => device can not be opened (error 2 "The system cannot find the file specified.") - Using NT device names instead ("\\.\COMx") which work in all cases. + char NTdevName[30] = "\\\\.\\"; // => "\\.\" + strncpy(NTdevName + 4, (char *)Data, 25); + /* NOTE: MS-DOS device names ("COMx") are not reliable if x + is > 9 !!! + => device can not be opened (error 2 "The system + cannot find the file specified.") Using NT device names + instead ("\\.\COMx") which work in all cases. */ - hCom_t = CreateFileA(NTdevName, // device name of the port - GENERIC_READ | GENERIC_WRITE, // read/write access - 0, // must be opened with exclusive-access - NULL, // default security attributes - OPEN_EXISTING, // must use OPEN_EXISTING - 0, // not overlapped I/O - NULL // must be NULL for comm devices - ); + hCom_t = CreateFileA( + NTdevName, // device name of the port + GENERIC_READ | GENERIC_WRITE, // read/write + // access + 0, // must be opened with + // exclusive-access + NULL, // default security attributes + OPEN_EXISTING, // must use + // OPEN_EXISTING + 0, // not overlapped I/O + NULL // must be NULL for comm devices + ); if (hCom_t != INVALID_HANDLE_VALUE) { CloseHandle(hCom_t); - char **templist = strlist_add(portlist, NTdevName, elems); + char **templist = + strlist_add(portlist, NTdevName, elems); if (!templist) { strlist_free(portlist, elems); return diag_pseterr(DIAG_ERR_NOMEM); @@ -593,12 +628,13 @@ char **diag_tty_getportlist(int *numports) { elems++; } } - szValueName = 256; // because RegEnumValue has changed value - szData = 256; // because RegEnumValue has changed value + szValueName = 256; // because RegEnumValue has changed value + szData = 256; // because RegEnumValue has changed value index++; - } //while - //std::sort(portlist.begin(), portlist.end()); // quicksort from - (void) RegCloseKey(hKey); + } // while + // std::sort(portlist.begin(), portlist.end()); // quicksort from + // + (void)RegCloseKey(hKey); } *numports = elems; diff --git a/scantool/diag_tty_win.h b/scantool/diag_tty_win.h index ca40131f..92d071c4 100644 --- a/scantool/diag_tty_win.h +++ b/scantool/diag_tty_win.h @@ -12,5 +12,5 @@ extern "C" { #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_TTY_WIN_H_ */ diff --git a/scantool/diag_vag.h b/scantool/diag_vag.h index e1cd851a..7d27ec01 100644 --- a/scantool/diag_vag.h +++ b/scantool/diag_vag.h @@ -32,92 +32,91 @@ extern "C" { /* * ECU Addresses, needs to be odd parity */ -#define DIAG_VAG_ECU_ALL 0x00 // Special: get fault codes from all -#define DIAG_VAG_ECU_ENGINE 0x01 // Engine electronic I -#define DIAG_VAG_ECU_GEARBOX 0x02 -#define DIAG_VAG_ECU_ABS 0x03 // Brake electronics -#define DIAG_VAG_ECU_EZS 0x05 // EZS / Kessy modul -#define DIAG_VAG_ECU_SEATPS 0x06 // Seat adjustment passenger side -#define DIAG_VAG_ECU_CENTDISP 0x07 // Central display system -#define DIAG_VAG_ECU_CLIMA 0x08 // Clima-/heating electronic -#define DIAG_VAG_ECU_CENTRAL 0x09 // Central electronic system -#define DIAG_VAG_ECU_ENGINE_II 0x11 // Engine electronic II -#define DIAG_VAG_ECU_CLUTCH 0x12 // Clutch electronic -#define DIAG_VAG_ECU_DISTADJ 0x13 // Automaticly distance adjustment -#define DIAG_VAG_ECU_SHOCKABS 0x14 // Wheel shock absorber electronic -#define DIAG_VAG_ECU_AIRBAGS 0x15 -#define DIAG_VAG_ECU_STEER 0x16 // Steering wheel electronic -#define DIAG_VAG_ECU_DASHBOARD 0x17 // Dashboard -#define DIAG_VAG_ECU_HEATING 0x18 // Aux-/Independent-heating -#define DIAG_VAG_ECU_GATEWAY 0x19 // Gateway K<>CAN -#define DIAG_VAG_ECU_ENGINE_III 0x21 // Engine electronic III -#define DIAG_VAG_ECU_4WD 0x22 // 4 Wheel-drive system -#define DIAG_VAG_ECU_BREAKAMP 0x23 // Break amplifier -#define DIAG_VAG_ECU_TRACTION 0x24 // Traction -#define DIAG_VAG_ECU_IMMO 0x25 // Immobilizer -#define DIAG_VAG_ECU_ELROOF 0x26 // El. Roof electronic -#define DIAG_VAG_ECU_CENTDISPR 0x27 // Central display rear -#define DIAG_VAG_ECU_LIGHT 0x29 // Light adjustment system -#define DIAG_VAG_ECU_NIVEAU 0x34 // Niveau system -#define DIAG_VAG_ECU_CENTLOCK 0x35 // Door locking system -#define DIAG_VAG_ECU_SEATDS 0x36 // Seat adjustment driver side -#define DIAG_VAG_ECU_NAVIGAT 0x37 // Navigation system -#define DIAG_VAG_ECU_LIGHTR 0x39 // Light adjustment system right-side -#define DIAG_VAG_ECU_DIESELPUMP 0x41 // Diesel pump electronic -#define DIAG_VAG_ECU_BREAKSUP 0x43 // Break support -#define DIAG_VAG_ECU_STEERHELP 0x44 // Steering help system -#define DIAG_VAG_ECU_INTERIMON 0x45 // Interior Monitoring -#define DIAG_VAG_ECU_LOCKS 0x45 +#define DIAG_VAG_ECU_ALL 0x00 // Special: get fault codes from all +#define DIAG_VAG_ECU_ENGINE 0x01 // Engine electronic I +#define DIAG_VAG_ECU_GEARBOX 0x02 +#define DIAG_VAG_ECU_ABS 0x03 // Brake electronics +#define DIAG_VAG_ECU_EZS 0x05 // EZS / Kessy modul +#define DIAG_VAG_ECU_SEATPS 0x06 // Seat adjustment passenger side +#define DIAG_VAG_ECU_CENTDISP 0x07 // Central display system +#define DIAG_VAG_ECU_CLIMA 0x08 // Clima-/heating electronic +#define DIAG_VAG_ECU_CENTRAL 0x09 // Central electronic system +#define DIAG_VAG_ECU_ENGINE_II 0x11 // Engine electronic II +#define DIAG_VAG_ECU_CLUTCH 0x12 // Clutch electronic +#define DIAG_VAG_ECU_DISTADJ 0x13 // Automaticly distance adjustment +#define DIAG_VAG_ECU_SHOCKABS 0x14 // Wheel shock absorber electronic +#define DIAG_VAG_ECU_AIRBAGS 0x15 +#define DIAG_VAG_ECU_STEER 0x16 // Steering wheel electronic +#define DIAG_VAG_ECU_DASHBOARD 0x17 // Dashboard +#define DIAG_VAG_ECU_HEATING 0x18 // Aux-/Independent-heating +#define DIAG_VAG_ECU_GATEWAY 0x19 // Gateway K<>CAN +#define DIAG_VAG_ECU_ENGINE_III 0x21 // Engine electronic III +#define DIAG_VAG_ECU_4WD 0x22 // 4 Wheel-drive system +#define DIAG_VAG_ECU_BREAKAMP 0x23 // Break amplifier +#define DIAG_VAG_ECU_TRACTION 0x24 // Traction +#define DIAG_VAG_ECU_IMMO 0x25 // Immobilizer +#define DIAG_VAG_ECU_ELROOF 0x26 // El. Roof electronic +#define DIAG_VAG_ECU_CENTDISPR 0x27 // Central display rear +#define DIAG_VAG_ECU_LIGHT 0x29 // Light adjustment system +#define DIAG_VAG_ECU_NIVEAU 0x34 // Niveau system +#define DIAG_VAG_ECU_CENTLOCK 0x35 // Door locking system +#define DIAG_VAG_ECU_SEATDS 0x36 // Seat adjustment driver side +#define DIAG_VAG_ECU_NAVIGAT 0x37 // Navigation system +#define DIAG_VAG_ECU_LIGHTR 0x39 // Light adjustment system right-side +#define DIAG_VAG_ECU_DIESELPUMP 0x41 // Diesel pump electronic +#define DIAG_VAG_ECU_BREAKSUP 0x43 // Break support +#define DIAG_VAG_ECU_STEERHELP 0x44 // Steering help system +#define DIAG_VAG_ECU_INTERIMON 0x45 // Interior Monitoring +#define DIAG_VAG_ECU_LOCKS 0x45 #if notdef -#define DIAG_VAG_ECU_CENTRAL 0x46 // Central modul comfort-system +# define DIAG_VAG_ECU_CENTRAL 0x46 // Central modul comfort-system #endif -#define DIAG_VAG_ECU_SOUND 0x47 // Sound system -#define DIAG_VAG_ECU_AUTLIGHT 0x49 // Automatical light switch -#define DIAG_VAG_ECU_ECM 0x4B // Emergency control monitoring -#define DIAG_VAG_ECU_ELTRAC 0x51 // Electrical traction -#define DIAG_VAG_ECU_SPOILER 0x54 // Rear spoiler -#define DIAG_VAG_ECU_LWR 0x55 // Headlamp leveling device -#define DIAG_VAG_ECU_RADIO 0x56 // Radio -#define DIAG_VAG_ECU_TVTUNER 0x57 // TV-Tuner -#define DIAG_VAG_ECU_TANK 0x58 // Additional tank -#define DIAG_VAG_ECU_TOWSEC 0x59 // Tow security system -#define DIAG_VAG_ECU_BATTADJ 0x61 // Battery adjustment/control -#define DIAG_VAG_ECU_TYREPRES 0x65 // Tyre pressure modul -#define DIAG_VAG_ECU_SEAT 0x66 // Seat-/mirror-adjustment -#define DIAG_VAG_ECU_SPEECH 0x67 // Speech control system -#define DIAG_VAG_ECU_WIPER 0x68 // Wiper modul -#define DIAG_VAG_ECU_TRAILER 0x69 // Trailer function -#define DIAG_VAG_ECU_BATTLOAD 0x71 // Battery loading system -#define DIAG_VAG_ECU_EMERGENCY 0x75 // Emergency system -#define DIAG_VAG_ECU_PARKING 0x76 // Parking help system -#define DIAG_VAG_ECU_SLD 0x78 // Sliding door - +#define DIAG_VAG_ECU_SOUND 0x47 // Sound system +#define DIAG_VAG_ECU_AUTLIGHT 0x49 // Automatical light switch +#define DIAG_VAG_ECU_ECM 0x4B // Emergency control monitoring +#define DIAG_VAG_ECU_ELTRAC 0x51 // Electrical traction +#define DIAG_VAG_ECU_SPOILER 0x54 // Rear spoiler +#define DIAG_VAG_ECU_LWR 0x55 // Headlamp leveling device +#define DIAG_VAG_ECU_RADIO 0x56 // Radio +#define DIAG_VAG_ECU_TVTUNER 0x57 // TV-Tuner +#define DIAG_VAG_ECU_TANK 0x58 // Additional tank +#define DIAG_VAG_ECU_TOWSEC 0x59 // Tow security system +#define DIAG_VAG_ECU_BATTADJ 0x61 // Battery adjustment/control +#define DIAG_VAG_ECU_TYREPRES 0x65 // Tyre pressure modul +#define DIAG_VAG_ECU_SEAT 0x66 // Seat-/mirror-adjustment +#define DIAG_VAG_ECU_SPEECH 0x67 // Speech control system +#define DIAG_VAG_ECU_WIPER 0x68 // Wiper modul +#define DIAG_VAG_ECU_TRAILER 0x69 // Trailer function +#define DIAG_VAG_ECU_BATTLOAD 0x71 // Battery loading system +#define DIAG_VAG_ECU_EMERGENCY 0x75 // Emergency system +#define DIAG_VAG_ECU_PARKING 0x76 // Parking help system +#define DIAG_VAG_ECU_SLD 0x78 // Sliding door /* * Block IDs "commands" */ -#define DIAG_VAG_CMD_ECU_INFO 0x00 -#define DIAG_VAG_CMD_TEST 0x04 -#define DIAG_VAG_CMD_DTC_CLEAR 0X05 -#define DIAG_VAG_CMD_END_COMMS 0X06 -#define DIAG_VAG_CMD_DTC_RQST 0X07 -#define DIAG_VAG_CMD_READ_DATA 0X08 -#define DIAG_VAG_CMD_RECODE 0x10 -#define DIAG_VAG_CMD_SET_GROUP 0x11 -#define DIAG_VAG_CMD_DATA_GROUP 0x12 -#define DIAG_VAG_CMD_ADP_READ 0x21 -#define DIAG_VAG_CMD_ADP_TEST 0x22 -#define DIAG_VAG_CMD_SET_OTHER 0x28 -#define DIAG_VAG_CMD_DATA_OTHER 0x29 -#define DIAG_VAG_CMD_ADP_SAVE 0x2A -#define DIAG_VAG_CMD_LOGIN 0x2B +#define DIAG_VAG_CMD_ECU_INFO 0x00 +#define DIAG_VAG_CMD_TEST 0x04 +#define DIAG_VAG_CMD_DTC_CLEAR 0X05 +#define DIAG_VAG_CMD_END_COMMS 0X06 +#define DIAG_VAG_CMD_DTC_RQST 0X07 +#define DIAG_VAG_CMD_READ_DATA 0X08 +#define DIAG_VAG_CMD_RECODE 0x10 +#define DIAG_VAG_CMD_SET_GROUP 0x11 +#define DIAG_VAG_CMD_DATA_GROUP 0x12 +#define DIAG_VAG_CMD_ADP_READ 0x21 +#define DIAG_VAG_CMD_ADP_TEST 0x22 +#define DIAG_VAG_CMD_SET_OTHER 0x28 +#define DIAG_VAG_CMD_DATA_OTHER 0x29 +#define DIAG_VAG_CMD_ADP_SAVE 0x2A +#define DIAG_VAG_CMD_LOGIN 0x2B -#define DIAG_VAG_RSP_DATA_NORMED 0xE7 //data with type information -#define DIAG_VAG_RSP_DATA 0xF4 //data with no type information -#define DIAG_VAG_RSP_ASCII 0xF6 -#define DIAG_VAG_RSP_HEX 0xFC +#define DIAG_VAG_RSP_DATA_NORMED 0xE7 // data with type information +#define DIAG_VAG_RSP_DATA 0xF4 // data with no type information +#define DIAG_VAG_RSP_ASCII 0xF6 +#define DIAG_VAG_RSP_HEX 0xFC #if defined(__cplusplus) } -#endif +# endif #endif /* _DIAG_VAG_H_ */ diff --git a/scantool/dyno.c b/scantool/dyno.c index 8017f75c..dcffee42 100644 --- a/scantool/dyno.c +++ b/scantool/dyno.c @@ -31,20 +31,19 @@ #include "diag_err.h" #include "dyno.h" - -#define SQR(_x_) ((_x_)*(_x_)) -#define CUB(_x_) ((_x_)*(_x_)*(_x_)) +#define SQR(_x_) ((_x_) * (_x_)) +#define CUB(_x_) ((_x_) * (_x_) * (_x_)) #define PI 3.141592654 #define MIN(_a_, _b_) (((_a_) < (_b_) ? (_a_) : (_b_))) /* generic measures table */ struct dyno_measure_table { - int size; /* allocated size */ - int nbr; /* number of elements in the table */ - union { /* table of measures */ - dyno_loss_measure * loss_measures; - dyno_measure * measures; - } meas; + int size; /* allocated size */ + int nbr; /* number of elements in the table */ + union { /* table of measures */ + dyno_loss_measure *loss_measures; + dyno_measure *measures; + } meas; }; /* measures and loss measures table */ @@ -54,56 +53,57 @@ struct dyno_measure_table measure_table; /* default size of measure table */ #define DYNO_DEFAULT_TABLE_SIZE 100 - /***************************************************************************** * Table allocation * *****************************************************************************/ /* Check table allocated size before addind a new element */ -static int dyno_check_allocated_table(struct dyno_measure_table *table) { - int rv; - if (table->meas.measures == NULL) { - /* allocating the table */ - table->size = DYNO_DEFAULT_TABLE_SIZE; - table->nbr = 0; - rv = diag_malloc(&table->meas.measures, table->size); - if (rv != 0) { - return rv; - } - } else if (table->nbr == table->size) { - /* reallocating the table if maximum capacity is reached */ - dyno_measure *ptr; - - /* new table size */ - table->size *= 2; - - /* allocating, transfering data */ - rv = diag_malloc(&ptr, table->size); - if (rv != 0) { - return rv; - } - - memcpy(ptr, table->meas.measures, table->nbr * sizeof(*(table->meas.measures))); - - /* free old memory */ - free(table->meas.measures); - table->meas.measures = ptr; - } - return 0; +static int +dyno_check_allocated_table(struct dyno_measure_table *table) { + int rv; + if (table->meas.measures == NULL) { + /* allocating the table */ + table->size = DYNO_DEFAULT_TABLE_SIZE; + table->nbr = 0; + rv = diag_malloc(&table->meas.measures, table->size); + if (rv != 0) { + return rv; + } + } else if (table->nbr == table->size) { + /* reallocating the table if maximum capacity is reached */ + dyno_measure *ptr; + + /* new table size */ + table->size *= 2; + + /* allocating, transfering data */ + rv = diag_malloc(&ptr, table->size); + if (rv != 0) { + return rv; + } + + memcpy(ptr, table->meas.measures, + table->nbr * sizeof(*(table->meas.measures))); + + /* free old memory */ + free(table->meas.measures); + table->meas.measures = ptr; + } + return 0; } /* reset table content */ -static int dyno_table_reset(struct dyno_measure_table *table) { - if (table->meas.measures != NULL) { - free(table->meas.measures); - table->meas.measures = NULL; - } - - table->size = 0; - table->nbr = 0; - return 0; -} +static int +dyno_table_reset(struct dyno_measure_table *table) { + if (table->meas.measures != NULL) { + free(table->meas.measures); + table->meas.measures = NULL; + } + table->size = 0; + table->nbr = 0; + return 0; +} /***************************************************************************** * Mass * @@ -115,19 +115,20 @@ int dyno_mass; /* * Sets the mass of the vehicle */ -int dyno_set_mass(int mass) { - dyno_mass = mass; - return DYNO_OK; +int +dyno_set_mass(int mass) { + dyno_mass = mass; + return DYNO_OK; } /* * Gets the mass of the vehicle */ -int dyno_get_mass() { - return dyno_mass; +int +dyno_get_mass() { + return dyno_mass; } - /***************************************************************************** * Gear * *****************************************************************************/ @@ -141,21 +142,22 @@ int dyno_gear; /* * Set ratio from speed (m/s * 1000) and rpm */ -int dyno_set_gear(int speed, int rpm) { - dyno_gear = speed * DYNO_GEAR_ACCURACY / rpm; - return DYNO_OK; +int +dyno_set_gear(int speed, int rpm) { + dyno_gear = speed * DYNO_GEAR_ACCURACY / rpm; + return DYNO_OK; } /* * Get speed (in m/s * 1000) from rpm */ -int dyno_get_speed_from_rpm(int rpm) { - int speed; - speed = rpm * dyno_gear / DYNO_GEAR_ACCURACY; /* m/s * 1000 */ - return speed; +int +dyno_get_speed_from_rpm(int rpm) { + int speed; + speed = rpm * dyno_gear / DYNO_GEAR_ACCURACY; /* m/s * 1000 */ + return speed; } - /***************************************************************************** * Loss measures * *****************************************************************************/ @@ -164,24 +166,25 @@ int dyno_get_speed_from_rpm(int rpm) { * How can "dyno_loss_needs_calculation" default to false? * How come when we reset it it still doesn't need calculation? */ -int dyno_loss_needs_calculation=0; +int dyno_loss_needs_calculation = 0; /* Add loss measure */ -int dyno_loss_add_measure(int millis, int speed) { - /* check memory allocation */ - dyno_check_allocated_table(&loss_measure_table); +int +dyno_loss_add_measure(int millis, int speed) { + /* check memory allocation */ + dyno_check_allocated_table(&loss_measure_table); - /* storing measure */ - loss_measure_table.meas.loss_measures[loss_measure_table.nbr].millis = millis; - loss_measure_table.meas.loss_measures[loss_measure_table.nbr].speed = speed; + /* storing measure */ + loss_measure_table.meas.loss_measures[loss_measure_table.nbr].millis = millis; + loss_measure_table.meas.loss_measures[loss_measure_table.nbr].speed = speed; - /* one measure added */ - loss_measure_table.nbr++; + /* one measure added */ + loss_measure_table.nbr++; - /* d and f need to be re-calculated */ - dyno_loss_needs_calculation = 1; + /* d and f need to be re-calculated */ + dyno_loss_needs_calculation = 1; - return DYNO_OK; + return DYNO_OK; } /* @@ -204,102 +207,107 @@ double dyno_loss_f; */ /* get acceleration between 2 measures (m/s^2) */ -static double dyno_loss_a_inter(int i, int j) { - double a; - dyno_loss_measure *measure0; - dyno_loss_measure *measure1; - - /* avoid bad use */ - if ((i < 0) || (i >= j) || (j > loss_measure_table.nbr)) { - return 0; - } - - /* select measures */ - measure0 = &loss_measure_table.meas.loss_measures[i]; - measure1 = &loss_measure_table.meas.loss_measures[j]; - - /* get acceleration */ - a = 1.0 - * (measure1->speed - measure0->speed) - / (measure1->millis - measure0->millis); - - return a; +static double +dyno_loss_a_inter(int i, int j) { + double a; + dyno_loss_measure *measure0; + dyno_loss_measure *measure1; + + /* avoid bad use */ + if ((i < 0) || (i >= j) || (j > loss_measure_table.nbr)) { + return 0; + } + + /* select measures */ + measure0 = &loss_measure_table.meas.loss_measures[i]; + measure1 = &loss_measure_table.meas.loss_measures[j]; + + /* get acceleration */ + a = 1.0 * (measure1->speed - measure0->speed) / + (measure1->millis - measure0->millis); + + return a; } /* a(i) (m/s^2) */ -static double dyno_loss_a(int i) { - double a; - - if (i <= 0) { - a = dyno_loss_a_inter(0, 1); - } else if (i >= loss_measure_table.nbr - 1) { - a = dyno_loss_a_inter(loss_measure_table.nbr - 2, - loss_measure_table.nbr - 1); - } else { - a = (dyno_loss_a_inter(i - 1, i) + dyno_loss_a_inter(i, i + 1)) / 2; - } - - return a; +static double +dyno_loss_a(int i) { + double a; + + if (i <= 0) { + a = dyno_loss_a_inter(0, 1); + } else if (i >= loss_measure_table.nbr - 1) { + a = dyno_loss_a_inter(loss_measure_table.nbr - 2, + loss_measure_table.nbr - 1); + } else { + a = (dyno_loss_a_inter(i - 1, i) + dyno_loss_a_inter(i, i + 1)) / 2; + } + + return a; } /* get y(i) */ -static double dyno_loss_y(int i) { - return (0 - dyno_mass * dyno_loss_a(i)); +static double +dyno_loss_y(int i) { + return (0 - dyno_mass * dyno_loss_a(i)); } /* Calculate d and f factors */ -static int dyno_loss_calculate(void) { - int i, nb; - double sum; - dyno_loss_measure *measure0; - dyno_loss_measure *measure1; - - /* calculate d */ - nb = loss_measure_table.nbr - 1; - sum = 0; - for (i=0; ispeed/1000.0) - SQR(measure0->speed/1000.0)); - sum += d; - } - dyno_loss_d = sum / nb; - - /* calculate f */ - nb = loss_measure_table.nbr; - sum = 0; - for (i=0; ispeed/1000.0)); - sum += f; - } - dyno_loss_f = sum / nb; - - dyno_loss_needs_calculation = 0; - - return DYNO_OK; +static int +dyno_loss_calculate(void) { + int i, nb; + double sum; + dyno_loss_measure *measure0; + dyno_loss_measure *measure1; + + /* calculate d */ + nb = loss_measure_table.nbr - 1; + sum = 0; + for (i = 0; i < nb; i++) { + double d; + + /* select measures */ + measure0 = &loss_measure_table.meas.loss_measures[i]; + measure1 = &loss_measure_table.meas.loss_measures[i + 1]; + + d = (dyno_loss_y(i + 1) - dyno_loss_y(i)) / + (SQR(measure1->speed / 1000.0) - SQR(measure0->speed / 1000.0)); + sum += d; + } + dyno_loss_d = sum / nb; + + /* calculate f */ + nb = loss_measure_table.nbr; + sum = 0; + for (i = 0; i < nb; i++) { + double f; + + measure0 = &loss_measure_table.meas.loss_measures[i]; + + f = dyno_loss_y(i) - (dyno_loss_d * SQR(measure0->speed / 1000.0)); + sum += f; + } + dyno_loss_f = sum / nb; + + dyno_loss_needs_calculation = 0; + + return DYNO_OK; } /* Reset all dyno loss measures */ -int dyno_loss_reset() { - dyno_table_reset(&loss_measure_table); - - dyno_loss_d = 0; - dyno_loss_f = 0; - dyno_loss_needs_calculation = 0; - return 0; +int +dyno_loss_reset() { + dyno_table_reset(&loss_measure_table); + + dyno_loss_d = 0; + dyno_loss_f = 0; + dyno_loss_needs_calculation = 0; + return 0; } /* Get d value */ -double dyno_loss_get_d() { +double +dyno_loss_get_d() { if (dyno_loss_needs_calculation == 1) { dyno_loss_calculate(); } @@ -308,7 +316,8 @@ double dyno_loss_get_d() { } /* Get f value */ -double dyno_loss_get_f() { +double +dyno_loss_get_f() { if (dyno_loss_needs_calculation == 1) { dyno_loss_calculate(); } @@ -316,26 +325,29 @@ double dyno_loss_get_f() { return dyno_loss_f; } -void dyno_loss_set_d(double d) { - dyno_loss_d = d; +void +dyno_loss_set_d(double d) { + dyno_loss_d = d; } -void dyno_loss_set_f(double f) { - dyno_loss_f = f; +void +dyno_loss_set_f(double f) { + dyno_loss_f = f; } /* Calculate loss power from speed (m/s2 * 1000) */ -static long dyno_loss_power(long speed) { - double power; +static long +dyno_loss_power(long speed) { + double power; - if (dyno_loss_needs_calculation == 1) { - dyno_loss_calculate(); - } + if (dyno_loss_needs_calculation == 1) { + dyno_loss_calculate(); + } - /* Pl = d * v^3 + f * v */ - power = dyno_loss_d * CUB(speed/1000.0) + dyno_loss_f * (speed/1000.0); + /* Pl = d * v^3 + f * v */ + power = dyno_loss_d * CUB(speed / 1000.0) + dyno_loss_f * (speed / 1000.0); - return (long)(power + .50); + return (long)(power + .50); } /***************************************************************************** @@ -343,99 +355,109 @@ static long dyno_loss_power(long speed) { *****************************************************************************/ /* Add a measure */ -int dyno_add_measure(int millis, int rpm) { - /* check memory allocation */ - dyno_check_allocated_table(&measure_table); +int +dyno_add_measure(int millis, int rpm) { + /* check memory allocation */ + dyno_check_allocated_table(&measure_table); - /* storing measure */ - measure_table.meas.measures[measure_table.nbr].millis = millis; - measure_table.meas.measures[measure_table.nbr].rpm = rpm; + /* storing measure */ + measure_table.meas.measures[measure_table.nbr].millis = millis; + measure_table.meas.measures[measure_table.nbr].rpm = rpm; - /* one measure added */ - measure_table.nbr++; + /* one measure added */ + measure_table.nbr++; - return DYNO_OK; + return DYNO_OK; } /* Reset all dyno data */ -int dyno_reset() { - return dyno_table_reset(&measure_table); +int +dyno_reset() { + return dyno_table_reset(&measure_table); } /* Get number of measures */ -int dyno_get_nb_measures() { - return measure_table.nbr; +int +dyno_get_nb_measures() { + return measure_table.nbr; } /* Get all measures */ -int dyno_get_measures(dyno_measure *measures, int size) { - /* copy measures */ - memcpy(measures, measure_table.meas.measures, MIN(size, measure_table.nbr) * sizeof(dyno_measure)); +int +dyno_get_measures(dyno_measure *measures, int size) { + /* copy measures */ + memcpy(measures, measure_table.meas.measures, + MIN(size, measure_table.nbr) * sizeof(dyno_measure)); - return DYNO_OK; + return DYNO_OK; } - /***************************************************************************** * Results * *****************************************************************************/ /* Calculate torque from power and RPM (power : W, RPM : rpm, torque : N.m) */ -#define TORQUE(_power_, _rpm_) (((_power_) * 60) / ((_rpm_) * 2 * PI)) +#define TORQUE(_power_, _rpm_) (((_power_)*60) / ((_rpm_)*2 * PI)) /* Convert power (W to ch DYN) */ -#define POWER_CH(_power_) ((_power_) * 10 / 7355) +#define POWER_CH(_power_) ((_power_)*10 / 7355) /* * Calculate power between 2 acceleration measures */ -static void dyno_calculate_result(dyno_measure *measure0, dyno_measure *measure1, dyno_result *result) { - /* effective power and lost power */ - int p_dyno, p_loss; - - /* calculate effective power from cinetic energy variation */ - p_dyno = SQR(dyno_get_speed_from_rpm(measure1->rpm)) - - SQR(dyno_get_speed_from_rpm(measure0->rpm)); /* m2/s2 * 1.000.000 */ - p_dyno = (p_dyno / (measure1->millis - measure0->millis)); /* m2/s3 */ - p_dyno = p_dyno * dyno_mass / 2000; - - /* calculate loss power at given speed */ - result->rpm = (measure0->rpm + measure1->rpm) / 2; - p_loss = dyno_loss_power(dyno_get_speed_from_rpm(result->rpm)); - - /* rpm, power and torque */ - result->power = p_dyno + p_loss; - result->power_ch = POWER_CH(result->power); - result->torque = (int)(TORQUE(result->power, result->rpm) + .50); - - return; +static void +dyno_calculate_result(dyno_measure *measure0, dyno_measure *measure1, + dyno_result *result) { + /* effective power and lost power */ + int p_dyno, p_loss; + + /* calculate effective power from cinetic energy variation */ + p_dyno = SQR(dyno_get_speed_from_rpm(measure1->rpm)) - + SQR(dyno_get_speed_from_rpm(measure0->rpm)); /* m2/s2 * 1.000.000 */ + p_dyno = (p_dyno / (measure1->millis - measure0->millis)); /* m2/s3 */ + p_dyno = p_dyno * dyno_mass / 2000; + + /* calculate loss power at given speed */ + result->rpm = (measure0->rpm + measure1->rpm) / 2; + p_loss = dyno_loss_power(dyno_get_speed_from_rpm(result->rpm)); + + /* rpm, power and torque */ + result->power = p_dyno + p_loss; + result->power_ch = POWER_CH(result->power); + result->torque = (int)(TORQUE(result->power, result->rpm) + .50); + + return; } /* * Calculate results */ -static void dyno_calculate_results(dyno_result *results) { - int i; - int nb = dyno_get_nb_results(); - - /* for each measure, calculate result */ - for (i=0; i saving mass...\n"); - - sprintf(buffer, "Mass (kg)\t%d\n", dyno_mass); - fwrite(buffer, strlen(buffer), sizeof(char), fd); - - sprintf(buffer, "\n"); - fwrite(buffer, strlen(buffer), sizeof(char), fd); - - - /* saving results */ - printf("-> saving results...\n"); - - sprintf(buffer, "Run results\n"); - fwrite(buffer, strlen(buffer), sizeof(char), fd); - - sprintf(buffer, "RPM\tPower (W)\tPower (ch)\tTorque (N.m)\n"); - fwrite(buffer, strlen(buffer), sizeof(char), fd); - - for (i=0; i saving mass...\n"); - /* saving run measures */ - if (measure_table.nbr > 0) { - printf("-> saving run measures...\n"); + sprintf(buffer, "Mass (kg)\t%d\n", dyno_mass); + fwrite(buffer, strlen(buffer), sizeof(char), fd); - sprintf(buffer, "Run measures\n"); - fwrite(buffer, strlen(buffer), sizeof(char), fd); + sprintf(buffer, "\n"); + fwrite(buffer, strlen(buffer), sizeof(char), fd); - sprintf(buffer, "Time (ms)\tRPM\tSpeed (m/s)\tSpeed (km/h)\n"); - fwrite(buffer, strlen(buffer), sizeof(char), fd); + /* saving results */ + printf("-> saving results...\n"); - for (i=0; i saving friction and aerodynamic parameters...\n"); + sprintf(buffer, "\n"); + fwrite(buffer, strlen(buffer), sizeof(char), fd); + + /* saving run measures */ + if (measure_table.nbr > 0) { + printf("-> saving run measures...\n"); + + sprintf(buffer, "Run measures\n"); + fwrite(buffer, strlen(buffer), sizeof(char), fd); + + sprintf(buffer, "Time (ms)\tRPM\tSpeed (m/s)\tSpeed (km/h)\n"); + fwrite(buffer, strlen(buffer), sizeof(char), fd); + + for (i = 0; i < measure_table.nbr; i++) { + sprintf(buffer, "%d\t%d\t%7.3f\t%7.3f\n", + measure_table.meas.measures[i].millis, + measure_table.meas.measures[i].rpm, + dyno_get_speed_from_rpm( + measure_table.meas.measures[i].rpm) / + 1000.0, + dyno_get_speed_from_rpm( + measure_table.meas.measures[i].rpm) * + 3.6 / 1000.0); + fwrite(buffer, strlen(buffer), sizeof(char), fd); + } + + sprintf(buffer, "\n"); + fwrite(buffer, strlen(buffer), sizeof(char), fd); + } - sprintf(buffer, "d and f loss parameters\n"); - fwrite(buffer, strlen(buffer), sizeof(char), fd); + /* saving d and f loss parameters */ + printf("-> saving friction and aerodynamic parameters...\n"); - sprintf(buffer, "d\t%8.5f\n", dyno_loss_d); - fwrite(buffer, strlen(buffer), sizeof(char), fd); + sprintf(buffer, "d and f loss parameters\n"); + fwrite(buffer, strlen(buffer), sizeof(char), fd); - sprintf(buffer, "f\t%8.2f\n", dyno_loss_f); - fwrite(buffer, strlen(buffer), sizeof(char), fd); + sprintf(buffer, "d\t%8.5f\n", dyno_loss_d); + fwrite(buffer, strlen(buffer), sizeof(char), fd); - sprintf(buffer, "\n"); - fwrite(buffer, strlen(buffer), sizeof(char), fd); + sprintf(buffer, "f\t%8.2f\n", dyno_loss_f); + fwrite(buffer, strlen(buffer), sizeof(char), fd); + sprintf(buffer, "\n"); + fwrite(buffer, strlen(buffer), sizeof(char), fd); - /* saving loss measures, if any */ - if (loss_measure_table.nbr > 0) { + /* saving loss measures, if any */ + if (loss_measure_table.nbr > 0) { - printf("-> saving loss measures...\n"); + printf("-> saving loss measures...\n"); - sprintf(buffer, "Loss measures\n"); - fwrite(buffer, strlen(buffer), sizeof(char), fd); + sprintf(buffer, "Loss measures\n"); + fwrite(buffer, strlen(buffer), sizeof(char), fd); - sprintf(buffer, "Time (ms)\tSpeed (m/s)\tSpeed (km/h)\n"); - fwrite(buffer, strlen(buffer), sizeof(char), fd); + sprintf(buffer, "Time (ms)\tSpeed (m/s)\tSpeed (km/h)\n"); + fwrite(buffer, strlen(buffer), sizeof(char), fd); - for (i=0; irxmsg) { /* Some data arrived from this ecu */ if (ep->rxmsg->data[byte] == val) { @@ -134,8 +130,6 @@ find_ecu_msg(int byte, databyte_type val) { return rxmsg; } - - /* * ************ * Basic routines to connect/interrogate an ECU @@ -161,28 +155,26 @@ j1979_data_rcv(void *handle, struct diag_msg *msg) { struct diag_msg *tmsg; unsigned int i; int ihandle; - ecu_data *ep; + ecu_data *ep; if (handle != NULL) { - ihandle= * (int *)handle; + ihandle = *(int *)handle; } else { ihandle = RQST_HANDLE_NORMAL; } - const char *O2_strings[] = { - "Test 0", - "Rich to lean sensor threshold voltage", - "Lean to rich sensor threshold voltage", - "Low sensor voltage for switch time calc.", - "High sensor voltage for switch time calc.", - "Rich to lean sensor switch time", - "Lean to rich sensor switch time", - "Minimum sensor voltage for test cycle", - "Maximum sensor voltage for test cycle", - "Time between sensor transitions" - }; - - if (diag_cli_debug & DIAG_DEBUG_DATA) { + const char *O2_strings[] = {"Test 0", + "Rich to lean sensor threshold voltage", + "Lean to rich sensor threshold voltage", + "Low sensor voltage for switch time calc.", + "High sensor voltage for switch time calc.", + "Rich to lean sensor switch time", + "Lean to rich sensor switch time", + "Minimum sensor voltage for test cycle", + "Maximum sensor voltage for test cycle", + "Time between sensor transitions"}; + + if (diag_cli_debug_load() & DIAG_DEBUG_DATA) { fprintf(stderr, "scantool: Got handle %p; %d bytes of data, src=0x%X, " "dest=0x%X\n", @@ -192,24 +184,23 @@ j1979_data_rcv(void *handle, struct diag_msg *msg) { /* Deal with the diag type responses (send/recv/watch) */ switch (ihandle) { - /* There is no difference between watch and decode ... */ - case RQST_HANDLE_WATCH: - case RQST_HANDLE_DECODE: - if (!(diag_cli_debug & DIAG_DEBUG_DATA)) { - /* Print data (unless done already) */ - diag_printmsg(stdout, msg, 0); - } - return; - break; - default: - break; + /* There is no difference between watch and decode ... */ + case RQST_HANDLE_WATCH: + case RQST_HANDLE_DECODE: + if (!(diag_cli_debug_load() & DIAG_DEBUG_DATA)) { + /* Print data (unless done already) */ + diag_printmsg(stdout, msg, 0); + } + return; + break; + default: + break; } - /* All other responses are J1979 response messages */ /* Clear out old messages */ - for (i=0, ep=ecu_info; irxmsg != NULL) { /* Old msg. release it */ diag_freemsg(ep->rxmsg); @@ -225,9 +216,9 @@ j1979_data_rcv(void *handle, struct diag_msg *msg) { uint8_t src = tmsg->src; unsigned int ecu_idx; struct diag_msg *rmsg; - bool found=0; + bool found = 0; - for (ecu_idx=0, ep=ecu_info; ecu_idxvalid) { if (ep->ecu_addr == src) { found = 1; @@ -264,148 +255,160 @@ j1979_data_rcv(void *handle, struct diag_msg *msg) { */ data = msg->data; switch (ihandle) { - case RQST_HANDLE_READINESS: - /* Handled in cmd_test_readiness() */ - break; - case RQST_HANDLE_NCMS: - case RQST_HANDLE_NCMS2: - /* - * Non Continuously Monitored System result - * NCMS2 prints everything, NCMS prints just failed - * tests - */ - if (data[0] != 0x46) { - fprintf(stderr, "Test 0x%02X failed %d\n", - data[1], data[2]); - return; - } - if ((data[1] & 0x1f) == 0) { - /* no Test support */ - return; - } - LL_FOREACH(msg, tmsg) { - int val, lim; - data = tmsg->data; - - val = (data[3]*255) + data[4]; - lim = (data[5]*255) + data[6]; - - if ((data[2] & 0x80) == 0) { - if (ihandle == RQST_HANDLE_NCMS2) { - /* Only print fails */ - if (val > lim) { - fprintf(stderr, "Test 0x%X Component 0x%X FAILED ", + case RQST_HANDLE_READINESS: + /* Handled in cmd_test_readiness() */ + break; + case RQST_HANDLE_NCMS: + case RQST_HANDLE_NCMS2: + /* + * Non Continuously Monitored System result + * NCMS2 prints everything, NCMS prints just failed + * tests + */ + if (data[0] != 0x46) { + fprintf(stderr, "Test 0x%02X failed %d\n", data[1], + data[2]); + return; + } + if ((data[1] & 0x1f) == 0) { + /* no Test support */ + return; + } + LL_FOREACH(msg, tmsg) { + int val, lim; + data = tmsg->data; + + val = (data[3] * 255) + data[4]; + lim = (data[5] * 255) + data[6]; + + if ((data[2] & 0x80) == 0) { + if (ihandle == RQST_HANDLE_NCMS2) { + /* Only print fails */ + if (val > lim) { + fprintf(stderr, + "Test 0x%X Component 0x%X " + "FAILED ", data[1], data[2] & 0x7f); - fprintf(stderr, "Max val %d Current Val %d\n", - lim, val); + fprintf(stderr, + "Max val %d Current Val " + "%d\n", + lim, val); + } + } else { + /* Max value test */ + fprintf(stderr, + "Test 0x%X Component 0x%X ", + data[1], data[2] & 0x7f); - } + if (val > lim) { + fprintf(stderr, "FAILED "); } else { - /* Max value test */ - fprintf(stderr, "Test 0x%X Component 0x%X ", - data[1], data[2] & 0x7f); - - if (val > lim) { - fprintf(stderr, "FAILED "); - } else { - fprintf(stderr, - "Passed" - " "); - } + fprintf(stderr, + "Passed" + " "); + } - fprintf(stderr, "Max val %d Current Val %d\n", + fprintf(stderr, + "Max val %d Current Val %d\n", lim, + val); + } + } else { + if (ihandle == RQST_HANDLE_NCMS2) { + if (val < lim) { + fprintf(stderr, + "Test 0x%X Component 0x%X " + "FAILED ", + data[1], data[2] & 0x7f); + fprintf(stderr, + "Min val %d Current Val " + "%d\n", lim, val); } } else { - if (ihandle == RQST_HANDLE_NCMS2) { - if (val < lim) { - fprintf(stderr, "Test 0x%X Component 0x%X FAILED ", - data[1], data[2] & 0x7f); - fprintf(stderr, "Min val %d Current Val %d\n", - lim, val); - } + /* Min value test */ + fprintf(stderr, + "Test 0x%X Component 0x%X ", + data[1], data[2] & 0x7f); + if (val < lim) { + fprintf(stderr, "FAILED "); } else { - /* Min value test */ - fprintf(stderr, "Test 0x%X Component 0x%X ", - data[1], data[2] & 0x7f); - if (val < lim) { - fprintf(stderr, "FAILED "); - } else { - fprintf(stderr, - "Passed" - " "); - } - - fprintf(stderr, "Min val %d Current Val %d\n", - lim, val); + fprintf(stderr, + "Passed" + " "); } + + fprintf(stderr, + "Min val %d Current Val %d\n", lim, + val); } } + } + return; + case RQST_HANDLE_O2S: + if (ecu_count > 1) { + fprintf(stderr, "ECU %d ", ecu_idx); + } + + /* O2 Sensor test results */ + if (msg->data[0] != 0x45) { + fprintf(stderr, "Test 0x%02X failed %d\n", msg->data[1], + msg->data[2]); return; - case RQST_HANDLE_O2S: - if (ecu_count > 1) { - fprintf(stderr, "ECU %d ", ecu_idx); - } + } + if ((data[1] & 0x1f) == 0) { + /* No Test support */ + } else { + int val = data[4]; + int min = data[5]; + int max = data[6]; + int failed; - /* O2 Sensor test results */ - if (msg->data[0] != 0x45) { - fprintf(stderr, "Test 0x%02X failed %d\n", - msg->data[1], msg->data[2]); - return; - } - if ((data[1] & 0x1f) == 0) { - /* No Test support */ + if ((val < min) || (val > max)) { + failed = 1; } else { - int val = data[4]; - int min = data[5]; - int max = data[6]; - int failed ; - - if ((val < min) || (val > max)) { - failed = 1; - } else { - failed = 0; - } + failed = 0; + } - switch (data[1]) { - case 1: /* Constant values voltages */ - case 2: - case 3: - case 4: - fprintf(stderr, "%s: %f\n", O2_strings[data[1]], - data[4]/200.0); - break; - case 5: - case 6: - case 9: - fprintf(stderr, "%s: actual %2.2f min %2.2f max %2.2f %s\n", - O2_strings[data[1]], data[4]/250.0, - data[5]/250.0, data[6]/250.0, - failed?"FAILED":"Passed" ); - break; - case 7: - case 8: - fprintf(stderr, "%s: %f %f %f %s\n", O2_strings[data[1]], - data[4]/200., - data[5]/200., - data[6]/200., - failed?"FAILED":"Passed" ); - break; - default: - fprintf(stderr, "Test %d: actual 0x%X min 0x%X max 0x%X %s\n", - data[1], data[4], - data[5], data[6], - failed?"FAILED":"Passed" ); - break; - } + switch (data[1]) { + case 1: /* Constant values voltages */ + case 2: + case 3: + case 4: + fprintf(stderr, "%s: %f\n", O2_strings[data[1]], + data[4] / 200.0); + break; + case 5: + case 6: + case 9: + fprintf(stderr, + "%s: actual %2.2f min %2.2f max %2.2f " + "%s\n", + O2_strings[data[1]], data[4] / 250.0, + data[5] / 250.0, data[6] / 250.0, + failed ? "FAILED" : "Passed"); + break; + case 7: + case 8: + fprintf(stderr, "%s: %f %f %f %s\n", + O2_strings[data[1]], data[4] / 200., + data[5] / 200., data[6] / 200., + failed ? "FAILED" : "Passed"); + break; + default: + fprintf(stderr, + "Test %d: actual 0x%X min 0x%X max 0x%X " + "%s\n", + data[1], data[4], data[5], data[6], + failed ? "FAILED" : "Passed"); + break; } - return; + } + return; } } return; } - /* * Receive callback routines, for watching mode, call * L3 (in this case SAE J1979) decode routine, if handle is NULL @@ -414,14 +417,15 @@ j1979_data_rcv(void *handle, struct diag_msg *msg) { void j1979_watch_rcv(void *handle, struct diag_msg *msg) { struct diag_msg *tmsg; - int i=0; + int i = 0; LL_FOREACH(msg, tmsg) { diag_printmsg_header(stderr, tmsg, 1, i); if (handle != NULL) { - char buf[256]; /* XXX Can we switch to stdargs for decoders? */ - diag_l3_decode((struct diag_l3_conn *)handle, tmsg, buf, sizeof(buf)); + char buf[256]; /* XXX Can we switch to stdargs for decoders? */ + diag_l3_decode((struct diag_l3_conn *)handle, tmsg, buf, + sizeof(buf)); fprintf(stderr, "%s\n", buf); } else { diag_data_dump(stderr, tmsg->data, tmsg->len); @@ -431,7 +435,6 @@ j1979_watch_rcv(void *handle, struct diag_msg *msg) { } } - void l2raw_data_rcv(UNUSED(void *handle), struct diag_msg *msg) { /* @@ -451,7 +454,7 @@ l2_check_pid_bits(uint8_t *data, int pid) { int offset; int bit; - pid--; /* (bits start at 0, pids at 1) */ + pid--; /* (bits start at 0, pids at 1) */ /* * Bits 1-8 are in byte 1, 9-16 in byte 2 etc * Same code is for PID requests for 0x40 and 0x60 @@ -459,7 +462,7 @@ l2_check_pid_bits(uint8_t *data, int pid) { while (pid > 0x20) { pid -= 0x20; } - offset = pid/8; + offset = pid / 8; bit = pid - (offset * 8); bit = 7 - bit; @@ -473,7 +476,7 @@ l2_check_pid_bits(uint8_t *data, int pid) { int l3_do_j1979_rqst(struct diag_l3_conn *d_conn, uint8_t mode, uint8_t p1, uint8_t p2, - uint8_t p3, uint8_t p4, uint8_t p5, uint8_t p6, void *handle) { + uint8_t p3, uint8_t p4, uint8_t p5, uint8_t p6, void *handle) { assert(d_conn != NULL); struct diag_msg msg = {0}; uint8_t data[7]; @@ -486,18 +489,18 @@ l3_do_j1979_rqst(struct diag_l3_conn *d_conn, uint8_t mode, uint8_t p1, uint8_t struct diag_msg *rxmsg; if (handle != NULL) { - ihandle= * (int *) handle; + ihandle = *(int *)handle; } else { ihandle = RQST_HANDLE_NORMAL; } /* Lengths of msg for each mode, 0 = this routine doesn't support */ // excludes headers and checksum. - uint8_t mode_lengths[] = { 0, 2, 3, 1, 1, 3, 2, 1, 7, 2 }; + uint8_t mode_lengths[] = {0, 2, 3, 1, 1, 3, 2, 1, 7, 2}; #define J1979_MODE_MAX 9 - if (diag_cli_debug & DIAG_DEBUG_DATA) { - fprintf(stderr, "j1979_rqst: handle %p conn %p mode %#02X\n", - handle, (void *)d_conn, mode); + if (diag_cli_debug_load() & DIAG_DEBUG_DATA) { + fprintf(stderr, "j1979_rqst: handle %p conn %p mode %#02X\n", handle, + (void *)d_conn, mode); } /* Put in src/dest etc, L3 or L2 may override/ignore them */ @@ -537,75 +540,75 @@ l3_do_j1979_rqst(struct diag_l3_conn *d_conn, uint8_t mode, uint8_t p1, uint8_t rv = diag_l3_recv(d_conn, 300, j1979_data_rcv, handle); if (rv < 0) { fprintf(stderr, "Retry failed, resynching...\n"); - rv= d_conn->d_l3_proto->diag_l3_proto_timer(d_conn, 6000); //force keepalive + rv = d_conn->d_l3_proto->diag_l3_proto_timer(d_conn, + 6000); // force + // keepalive if (rv < 0) { - fprintf(stderr, "\tfailed, connection to ECU may be lost!\n"); + fprintf(stderr, + "\tfailed, connection to ECU may be lost!\n"); return diag_iseterr(rv); } fprintf(stderr, "\tOK.\n"); return DIAG_ERR_TIMEOUT; - } } - //This part is super confusing: ihandle comes from the handle from a callback passed - //between L2 and L3 with handles to handles etc.. + // This part is super confusing: ihandle comes from the handle from a callback + // passed between L2 and L3 with handles to handles etc.. switch (ihandle) { - /* We dont process the info in watch/decode mode */ - case RQST_HANDLE_WATCH: - case RQST_HANDLE_DECODE: - return rv; - break; - default: - break; + /* We dont process the info in watch/decode mode */ + case RQST_HANDLE_WATCH: + case RQST_HANDLE_DECODE: + return rv; + break; + default: + break; } /* * Go thru the ecu_data and see what was received. */ - for (i=0, ep=ecu_info; irxmsg) { /* Some data arrived from this ecu */ rxmsg = ep->rxmsg; rxdata = ep->rxmsg->data; - /* A bit of ugliness is required to bail out on NegativeResponse messages when using - * an iso14230 L2. + /* A bit of ugliness is required to bail out on NegativeResponse + * messages when using an iso14230 L2. */ - if (d_conn->d_l3l2_conn->l2proto->diag_l2_protocol == DIAG_L2_PROT_ISO14230) { + if (d_conn->d_l3l2_conn->l2proto->diag_l2_protocol == + DIAG_L2_PROT_ISO14230) { if (rxdata[0] == 0x7f) { return DIAG_ERR_ECUSAIDNO; } } 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; - + case 1: + if (rxdata[0] != 0x41) { + ep->mode1_data[p1].type = TYPE_FAILED; 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; + } + 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) */ @@ -621,7 +624,7 @@ l3_do_send(struct diag_l3_conn *d_conn, void *data, size_t len, void *handle) { msg.src = global_cfg.src; msg.dest = global_cfg.tgt; - msg.len = (uint8_t) len; + msg.len = (uint8_t)len; msg.data = (uint8_t *)data; diag_l3_send(d_conn, &msg); @@ -670,7 +673,6 @@ l2_do_send(struct diag_l2_conn *d_conn, void *data, size_t len, void *handle) { return rv; } - /* * Clear data that is relevant to an ECU */ @@ -689,10 +691,11 @@ clear_data(void) { * Common start routine used by all protocols * - initialises the diagnostic layer * - opens a Layer 2 device for the specified Layer 1 protocol - * returns L2 file descriptor + * returns L2 file descriptor */ -static struct diag_l2_conn *do_l2_common_start(int L1protocol, int L2protocol, - flag_type type, unsigned int bitrate, target_type target, source_type source ) { +static struct diag_l2_conn * +do_l2_common_start(int L1protocol, int L2protocol, flag_type type, unsigned int bitrate, + target_type target, source_type source) { int rv; struct diag_l0_device *dl0d = global_dl0d; struct diag_l2_conn *d_conn = NULL; @@ -713,8 +716,7 @@ static struct diag_l2_conn *do_l2_common_start(int L1protocol, int L2protocol, rv = diag_l2_open(dl0d, L1protocol); if (rv) { - if ((rv != DIAG_ERR_BADIFADAPTER) && - (rv != DIAG_ERR_PROTO_NOTSUPP)) { + if ((rv != DIAG_ERR_BADIFADAPTER) && (rv != DIAG_ERR_PROTO_NOTSUPP)) { fprintf(stderr, "Failed to open hardware interface\n"); } @@ -723,8 +725,8 @@ static struct diag_l2_conn *do_l2_common_start(int L1protocol, int L2protocol, /* Now do the Layer 2 startcommunications */ - d_conn = diag_l2_StartCommunications(dl0d, L2protocol, type, - bitrate, target, source); + d_conn = diag_l2_StartCommunications(dl0d, L2protocol, type, bitrate, target, + source); if (d_conn == NULL) { diag_l2_close(dl0d); @@ -732,7 +734,6 @@ static struct diag_l2_conn *do_l2_common_start(int L1protocol, int L2protocol, 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 @@ -751,7 +752,6 @@ static struct diag_l2_conn *do_l2_common_start(int L1protocol, int L2protocol, return d_conn; } - /* * 9141 init */ @@ -760,8 +760,8 @@ do_l2_9141_start(int destaddr) { struct diag_l2_conn *d_conn; d_conn = do_l2_common_start(DIAG_L1_ISO9141, DIAG_L2_PROT_ISO9141, - DIAG_L2_TYPE_SLOWINIT, global_cfg.speed, (uint8_t)destaddr, - global_cfg.src); + DIAG_L2_TYPE_SLOWINIT, global_cfg.speed, + (uint8_t)destaddr, global_cfg.src); if (d_conn == NULL) { return diag_iseterr(DIAG_ERR_GENERAL); @@ -787,12 +787,12 @@ do_l2_14230_start(int init_type) { flags = 0; } - flags |= DIAG_L2_IDLE_J1978; /* Use J1978 idle msgs */ + flags |= DIAG_L2_IDLE_J1978; /* Use J1978 idle msgs */ - flags |= (init_type & DIAG_L2_TYPE_INITMASK) ; + flags |= (init_type & DIAG_L2_TYPE_INITMASK); - d_conn = do_l2_common_start(DIAG_L1_ISO14230, DIAG_L2_PROT_ISO14230, - flags, global_cfg.speed, global_cfg.tgt, global_cfg.src); + d_conn = do_l2_common_start(DIAG_L1_ISO14230, DIAG_L2_PROT_ISO14230, flags, + global_cfg.speed, global_cfg.tgt, global_cfg.src); if (d_conn == NULL) { return diag_iseterr(DIAG_ERR_GENERAL); @@ -812,8 +812,8 @@ do_l2_j1850_start(int l1_type) { flag_type flags = 0; struct diag_l2_conn *d_conn; - d_conn = do_l2_common_start(l1_type, DIAG_L2_PROT_SAEJ1850, - flags, global_cfg.speed, 0x6a, global_cfg.src); + d_conn = do_l2_common_start(l1_type, DIAG_L2_PROT_SAEJ1850, flags, + global_cfg.speed, 0x6a, global_cfg.src); if (d_conn == NULL) { return diag_iseterr(DIAG_ERR_GENERAL); @@ -825,20 +825,20 @@ do_l2_j1850_start(int l1_type) { return 0; } - /* * Gets the data for every supported test using global L3 connection * * 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_ipending()), which amounts to "was Enter pressed". + * becoming ready for read (using diag_os_ipending()), which amounts to "was Enter + * pressed". * * It is used in "Interuptible" mode when doing "monitor" command */ int do_j1979_getdata(int interruptible) { - unsigned int i,j; + unsigned int i, j; int rv; struct diag_l3_conn *d_conn; ecu_data *ep; @@ -849,16 +849,17 @@ do_j1979_getdata(int interruptible) { return diag_iseterr(DIAG_ERR_GENERAL); } - diag_os_ipending(); //this is necessary on WIN32 to "purge" the last state of the enter key; we can't just poll stdin. + diag_os_ipending(); // this is necessary on WIN32 to "purge" the last state of the + // enter key; we can't just poll stdin. /* * Now get all the data supported */ - for (i=3; i<0x100; i++) { + for (i = 3; i < 0x100; i++) { if (merged_mode1_info[i]) { fprintf(stderr, "Requesting Mode 1 Pid 0x%02X...\n", i); - rv = l3_do_j1979_rqst(d_conn, 0x1, (uint8_t) i, 0x00, - 0x00, 0x00, 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); + rv = l3_do_j1979_rqst(d_conn, 0x1, (uint8_t)i, 0x00, 0x00, 0x00, + 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); if (rv < 0) { fprintf(stderr, "Mode 1 Pid 0x%02X request failed (%d)\n", i, rv); @@ -882,8 +883,8 @@ do_j1979_getdata(int interruptible) { /* Get mode2/pid2 (DTC that caused freezeframe) */ fprintf(stderr, "Requesting Mode 0x02 Pid 0x02 (Freeze frame DTCs)...\n"); - rv = l3_do_j1979_rqst(d_conn, 0x2, 2, 0x00, - 0x00, 0x00, 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); + rv = l3_do_j1979_rqst(d_conn, 0x2, 2, 0x00, 0x00, 0x00, 0x00, 0x00, + (void *)&_RQST_HANDLE_NORMAL); if (rv < 0) { fprintf(stderr, "Mode 0x02 Pid 0x02 request failed (%d)\n", rv); @@ -894,27 +895,33 @@ do_j1979_getdata(int interruptible) { fprintf(stderr, "Mode 0x02 Pid 0x02 request no-data (%d)\n", rv); return DIAG_ERR_GENERAL; } - diag_os_ipending(); //again, required for WIN32 to "purge" last keypress + diag_os_ipending(); // again, required for WIN32 to "purge" last keypress /* Now go thru the ECUs that have responded with mode2 info */ - for (j=0, ep=ecu_info; jmode2_data[2].type == TYPE_GOOD) && - (ep->mode2_data[2].data[2] | - ep->mode2_data[2].data[3]) ) { - for (i=3; i<0x100; i++) { + for (j = 0, ep = ecu_info; j < ecu_count; j++, ep++) { + if ((ep->mode2_data[2].type == TYPE_GOOD) && + (ep->mode2_data[2].data[2] | ep->mode2_data[2].data[3])) { + for (i = 3; i < 0x100; i++) { if (ep->mode2_info[i]) { - fprintf(stderr, "Requesting Mode 0x02 Pid 0x%02X...\n", i); - rv = l3_do_j1979_rqst(d_conn, 0x2, (uint8_t)i, 0x00, - 0x00, 0x00, 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); + fprintf(stderr, + "Requesting Mode 0x02 Pid 0x%02X...\n", i); + rv = l3_do_j1979_rqst( + d_conn, 0x2, (uint8_t)i, 0x00, 0x00, 0x00, + 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); if (rv < 0) { - fprintf(stderr, "Mode 0x02 Pid 0x%02X request failed (%d)\n", i, rv); + fprintf(stderr, + "Mode 0x02 Pid 0x%02X request " + "failed (%d)\n", + i, rv); } else { msg = find_ecu_msg(0, 0x42); if (msg == NULL) { - fprintf(stderr, "Mode 0x02 Pid 0x%02X request no-data (%d)\n", i, rv); + fprintf(stderr, + "Mode 0x02 Pid 0x%02X " + "request no-data (%d)\n", + i, rv); return DIAG_ERR_GENERAL; } } - } if (interruptible) { if (diag_os_ipending()) { // was Enter @@ -933,7 +940,8 @@ do_j1979_getdata(int interruptible) { * * This is the basic work horse routine */ -void do_j1979_basics() { +void +do_j1979_basics() { ecu_data *ep; unsigned int i; int o2monitoring = 0; @@ -943,7 +951,7 @@ void do_j1979_basics() { */ do_j1979_getpids(); - global_state = STATE_SCANDONE ; + global_state = STATE_SCANDONE; /* * Get current DTCs/MIL lamp status/Tests supported for this ECU @@ -959,12 +967,13 @@ void do_j1979_basics() { /* * And now do stuff with that data */ - for (i=0, ep=ecu_info; imode1_data[2].type == TYPE_GOOD) && - (ep->mode1_data[2].data[2] | ep->mode1_data[2].data[3]) ) { + 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])) { fprintf(stderr, "ECU %d Freezeframe data exists, caused by DTC ", i); - print_single_dtc(ep->mode1_data[2].data[2] , ep->mode1_data[2].data[3]); + print_single_dtc(ep->mode1_data[2].data[2], + ep->mode1_data[2].data[3]); fprintf(stderr, "\n"); } @@ -990,7 +999,8 @@ void do_j1979_basics() { fprintf(stderr, "EOBD (Europe)"); break; default: - fprintf(stderr, "unknown (%d)", ep->mode1_data[0x1c].data[2]); + fprintf(stderr, "unknown (%d)", + ep->mode1_data[0x1c].data[2]); break; } fprintf(stderr, " compliant\n"); @@ -1000,8 +1010,8 @@ void do_j1979_basics() { * 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) ) { + if ((ep->mode1_data[1].type == TYPE_GOOD) && + (ep->mode1_data[1].data[4] & 0x20)) { o2monitoring = 1; } } @@ -1022,8 +1032,7 @@ print_single_dtc(databyte_type d0, databyte_type d1) { db[1] = d1; fprintf(stderr, "%s", - diag_dtc_decode(db, 2, NULL, NULL, dtc_proto_j2012, buf, - sizeof(buf))); + diag_dtc_decode(db, 2, NULL, NULL, dtc_proto_j2012, buf, sizeof(buf))); return 0; } @@ -1033,11 +1042,11 @@ print_dtcs(uint8_t *data, uint8_t len) { /* Print the DTCs just received */ int i, j; - for (i=0, j=1; (i<3) && ((j+1) < len); i++, j+=2) { + for (i = 0, j = 1; (i < 3) && ((j + 1) < len); i++, j += 2) { if ((data[j] == 0) && (data[j + 1] == 0)) { continue; } - print_single_dtc(data[j], data[j+1]); + print_single_dtc(data[j], data[j + 1]); } } @@ -1054,32 +1063,31 @@ do_j1979_cms() { d_conn = global_l3_conn; fprintf(stderr, "Requesting Mode 7 (Current cycle emission DTCs)...\n"); - rv = l3_do_j1979_rqst(d_conn, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); + rv = l3_do_j1979_rqst(d_conn, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + (void *)&_RQST_HANDLE_NORMAL); if (rv == DIAG_ERR_TIMEOUT) { /* Didn't get a response, this is valid if there are no DTCs */ fprintf(stderr, "No DTCs stored.\n"); return; } if (rv != 0) { - fprintf(stderr, "Failed to get test results for continuously monitored systems\n"); + fprintf(stderr, + "Failed to get test results for continuously monitored systems\n"); return; } fprintf(stderr, "Currently monitored DTCs: "); - for (i=0; idata, msg->len); } - } fprintf(stderr, "\n"); return; } - /* * Get test results for non-constantly monitored systems */ @@ -1088,7 +1096,7 @@ do_j1979_ncms(int printall) { int rv; struct diag_l3_conn *d_conn; unsigned int i, j; -// int supported=0; //not used ? + // int supported=0; //not used ? ecu_data *ep; uint8_t merged_mode6_info[0x100]; @@ -1097,12 +1105,12 @@ do_j1979_ncms(int printall) { /* Merge all ECU mode6 info into one place*/ memset(merged_mode6_info, 0, sizeof(merged_mode6_info)); - for (i=0, ep=ecu_info; imode6_info);j++) { - merged_mode6_info[j] |= ep->mode6_info[j] ; + for (i = 0, ep = ecu_info; i < ecu_count; i++, ep++) { + for (j = 0; j < sizeof(ep->mode6_info); j++) { + merged_mode6_info[j] |= ep->mode6_info[j]; } - //if (ep->mode6_info[0] != 0) //XXX not sure what this accomplished - //supported = 1; //this never gets used ... + // if (ep->mode6_info[0] != 0) //XXX not sure what this accomplished + // supported = 1; //this never gets used ... } if (merged_mode6_info[0] == 0x00) { @@ -1111,23 +1119,24 @@ do_j1979_ncms(int printall) { } if (merged_mode6_info[0] == 0x00) { - fprintf(stderr, "ECU doesn't support non-continuously monitored system tests\n"); + fprintf(stderr, + "ECU doesn't support non-continuously monitored system tests\n"); return; } /* * Now do the tests */ - for (i=0 ; i < 60; i++) { + for (i = 0; i < 60; i++) { if ((merged_mode6_info[i]) && ((i & 0x1f) != 0)) { /* Do test */ fprintf(stderr, "Requesting Mode 6 TestID 0x%02X...\n", i); - rv = l3_do_j1979_rqst(d_conn, 6, (uint8_t)i, 0x00, - 0x00, 0x00, 0x00, 0x00, - (void *)(printall? &_RQST_HANDLE_NCMS:&_RQST_HANDLE_NCMS2)); + rv = l3_do_j1979_rqst(d_conn, 6, (uint8_t)i, 0x00, 0x00, 0x00, + 0x00, 0x00, + (void *)(printall ? &_RQST_HANDLE_NCMS + : &_RQST_HANDLE_NCMS2)); if (rv < 0) { - fprintf(stderr, - "Mode 6 Test ID 0x%02X failed\n", i); + fprintf(stderr, "Mode 6 Test ID 0x%02X failed\n", i); } } } @@ -1136,9 +1145,10 @@ do_j1979_ncms(int printall) { /* * Get mode info - * response_offset : index into received packet where the the supported_pid bytemasks start. - * TODO: add return value to signal total failure (if l3_do_j1979_rqst lost the connection to - * the ECU) + * response_offset : index into received packet where the the supported_pid bytemasks + * start. + * TODO: add return value to signal total failure (if l3_do_j1979_rqst lost the connection + * to the ECU) */ void do_j1979_getmodeinfo(uint8_t mode, int response_offset) { @@ -1163,16 +1173,17 @@ do_j1979_getmodeinfo(uint8_t mode, int response_offset) { * Do Mode 'mode' Pid 'pid' request to find out * what is supported */ - fprintf(stderr, "Exploring Mode 0x%02X supported PIDs (block 0x%02X)...\n", mode, pid); - rv = l3_do_j1979_rqst(d_conn, mode, (uint8_t) pid, 0x00, - 0x00, 0x00, 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); + fprintf(stderr, "Exploring Mode 0x%02X supported PIDs (block 0x%02X)...\n", + mode, pid); + rv = l3_do_j1979_rqst(d_conn, mode, (uint8_t)pid, 0x00, 0x00, 0x00, 0x00, + 0x00, (void *)&_RQST_HANDLE_NORMAL); if (rv != 0) { /* No response */ break; } /* Process the results */ - for (j=0, ep=ecu_info, not_done = 0; jrxmsg == NULL) { continue; } @@ -1211,11 +1222,10 @@ do_j1979_getmodeinfo(uint8_t mode, int response_offset) { break; } - data[0] = 1; /* Pid 0, 0x20, 0x40 always supported */ - for (i=0 ; i<=0x20; i++) { - if (l2_check_pid_bits( - &ep->rxmsg->data[response_offset], - (int)i)) { + data[0] = 1; /* Pid 0, 0x20, 0x40 always supported */ + for (i = 0; i <= 0x20; i++) { + if (l2_check_pid_bits(&ep->rxmsg->data[response_offset], + (int)i)) { data[i + pid] = 1; } } @@ -1228,11 +1238,10 @@ do_j1979_getmodeinfo(uint8_t mode, int response_offset) { if (not_done == 0) { break; } - } //for + } // for return; } - /* * Get the supported PIDs and Tests (Mode 1, 2, 5, 6, 9) * @@ -1257,16 +1266,16 @@ do_j1979_getpids() { * for Mode5 */ memset(merged_mode1_info, 0, sizeof(merged_mode1_info)); - for (i=0, ep=ecu_info; imode1_info);j++) { - merged_mode1_info[j] |= ep->mode1_info[j] ; + for (i = 0, ep = ecu_info; i < ecu_count; i++, ep++) { + for (j = 0; j < sizeof(ep->mode1_info); j++) { + merged_mode1_info[j] |= ep->mode1_info[j]; } } memset(merged_mode5_info, 0, sizeof(merged_mode5_info)); - for (i=0, ep=ecu_info; imode5_info);j++) { - merged_mode5_info[j] |= ep->mode5_info[j] ; + for (i = 0, ep = ecu_info; i < ecu_count; i++, ep++) { + for (j = 0; j < sizeof(ep->mode5_info); j++) { + merged_mode5_info[j] |= ep->mode5_info[j]; } } return; @@ -1284,7 +1293,7 @@ do_j1979_O2tests() { return; } - for (i=0; i<=7; i++) { + for (i = 0; i <= 7; i++) { if (global_O2_sensors & (1 << i)) { do_j1979_getO2tests(i); } @@ -1292,7 +1301,6 @@ do_j1979_O2tests() { return; } - /* * Do O2 tests for O2Sensor * @@ -1305,19 +1313,18 @@ do_j1979_getO2tests(int O2sensor) { struct diag_l3_conn *d_conn; int i; - uint8_t o2s = 1<rxmsg) && (ep->rxmsg->data[0] == 0x41)) { /* Go thru received msgs looking for DTC responses */ if ((ep->mode1_data[1].data[3] & 0xf0) || @@ -1370,7 +1380,6 @@ do_j1979_getdtcs() { num_dtcs += ep->mode1_data[1].data[2] & 0x7f; } - } if (readiness == 1) { fprintf(stderr, "Not all readiness tests have completed\n"); @@ -1382,7 +1391,7 @@ do_j1979_getdtcs() { fprintf(stderr, "MIL light OFF, "); } - fprintf(stderr, "%d stored DTC%c\n", num_dtcs, (num_dtcs==1)?' ':'s'); + fprintf(stderr, "%d stored DTC%c\n", num_dtcs, (num_dtcs == 1) ? ' ' : 's'); if (num_dtcs) { /* @@ -1390,15 +1399,15 @@ do_j1979_getdtcs() { */ fprintf(stderr, "Requesting Mode 0x03 (Emission DTCs)...\n"); - rv = l3_do_j1979_rqst(d_conn, 3, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); - if ((rv < 0) || (find_ecu_msg(0, 0x43)==NULL)) { + rv = l3_do_j1979_rqst(d_conn, 3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + (void *)&_RQST_HANDLE_NORMAL); + if ((rv < 0) || (find_ecu_msg(0, 0x43) == NULL)) { fprintf(stderr, "ECU would not return DTCs\n"); return -1; } /* Go thru received msgs looking for DTC responses */ - for (i=0, ep=ecu_info; irxmsg) && (ep->rxmsg->data[0] == 0x43)) { struct diag_msg *msg; LL_FOREACH(ep->rxmsg, msg) { @@ -1428,20 +1437,20 @@ do_j1979_getO2sensors() { num_sensors = 0; fprintf(stderr, "Requesting Mode 0x01 PID 0x13 (O2 sensors location)...\n"); - rv = l3_do_j1979_rqst(d_conn, 1, 0x13, 0, - 0x00, 0x00, 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); + rv = l3_do_j1979_rqst(d_conn, 1, 0x13, 0, 0x00, 0x00, 0x00, 0x00, + (void *)&_RQST_HANDLE_NORMAL); - if ((rv < 0) || (find_ecu_msg(0, 0x41)==NULL)) { + if ((rv < 0) || (find_ecu_msg(0, 0x41) == NULL)) { fprintf(stderr, "Mode 1 Pid 0x13 request failed %d\n", rv); return 0; } - for (i=0, ep=ecu_info; irxmsg) && (ep->rxmsg->data[0] == 0x41)) { /* Maintain bitmap of sensors */ global_O2_sensors |= ep->rxmsg->data[2]; /* And count additional sensors on this ECU */ - for (j=0; j<=7; j++) { + for (j = 0; j <= 7; j++) { if (ep->rxmsg->data[2] & (1 << j)) { num_sensors++; } @@ -1459,12 +1468,12 @@ diag_cleardtc(void) { /* Clear DTCs */ struct diag_l3_conn *d_conn; int rv; - struct diag_msg *rxmsg; + struct diag_msg *rxmsg; d_conn = global_l3_conn; fprintf(stderr, "Requesting Mode 0x04 (Clear DTCs)...\n"); - rv = l3_do_j1979_rqst(d_conn, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); + rv = l3_do_j1979_rqst(d_conn, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + (void *)&_RQST_HANDLE_NORMAL); rxmsg = find_ecu_msg(0, 0x44); @@ -1476,12 +1485,12 @@ diag_cleardtc(void) { return rv; } -typedef int (start_fn)(int); +typedef int(start_fn)(int); struct protocol { - const char *desc; + const char *desc; start_fn *start; - int flags; + int flags; }; const struct protocol protocols[] = { @@ -1543,7 +1552,7 @@ ecu_connect(void) { break; } - if (diag_cli_debug) { + if (diag_cli_debug_load()) { fprintf(stderr, "debug: L2 connection ID %p, L3 ID %p\n", (void *)global_l2_conn, (void *)global_l3_conn); } @@ -1551,7 +1560,6 @@ ecu_connect(void) { return rv ? diag_iseterr(rv) : 0; } - /* * Initialise */ @@ -1565,197 +1573,168 @@ do_init(void) { /* * Explain command line usage */ -static void do_usage (void) { - fprintf( stderr, "FreeDiag ScanTool:\n\n" ) ; - fprintf( stderr, " Usage -\n" ) ; - fprintf( stderr, " scantool [-h][-a|-c][-f Runs the commands from at startup\n"); - fprintf( stderr, "\n" ) ; +static void +do_usage(void) { + fprintf(stderr, "FreeDiag ScanTool:\n\n"); + fprintf(stderr, " Usage -\n"); + fprintf(stderr, " scantool [-h][-a|-c][-f Runs the commands from at startup\n"); + fprintf(stderr, "\n"); } +static void +format_o2(char *buf, int maxlen, UNUSED(int english), const struct pid *p, response *data, + int n) { + double v = DATA_SCALED(p, DATA_1(p, n, data)); + int t = DATA_1(p, n + 1, data); - -static void format_o2(char *buf, int maxlen, UNUSED(int english), - const struct pid *p, response *data, int n) { - double v = DATA_SCALED(p, DATA_1(p, n, data)); - int t = DATA_1(p, n + 1, data); - - if (t == 0xff) { - snprintf(buf, maxlen, p->fmt1, v); - } else { - snprintf(buf, maxlen, p->fmt2, v, - t * p->scale2 + p->offset2); - } + if (t == 0xff) { + snprintf(buf, maxlen, p->fmt1, v); + } else { + snprintf(buf, maxlen, p->fmt2, v, t * p->scale2 + p->offset2); + } } - static void -format_aux(char *buf, int maxlen, UNUSED(int english), const struct pid *p, - response *data, int n) { - snprintf(buf, maxlen, (DATA_RAW(p, n, data) & 1) ? "PTO Active" : "----"); +format_aux(char *buf, int maxlen, UNUSED(int english), const struct pid *p, response *data, + int n) { + snprintf(buf, maxlen, (DATA_RAW(p, n, data) & 1) ? "PTO Active" : "----"); } - - static void format_fuel(char *buf, int maxlen, UNUSED(int english), const struct pid *p, - response *data, int n) { - int s = DATA_1(p, n, data); + response *data, int n) { + int s = DATA_1(p, n, data); - switch (s) { - case 1 << 0: - snprintf(buf, maxlen, "Open"); - break; - case 1 << 1: - snprintf(buf, maxlen, "Closed"); - break; - case 1 << 2: - snprintf(buf, maxlen, "Open-Driving"); - break; - case 1 << 3: - snprintf(buf, maxlen, "Open-Fault"); - break; - case 1 << 4: - snprintf(buf, maxlen, "Closed-Fault"); - break; - default: - snprintf(buf, maxlen, "Open(rsvd)"); - break; - } + switch (s) { + case 1 << 0: + snprintf(buf, maxlen, "Open"); + break; + case 1 << 1: + snprintf(buf, maxlen, "Closed"); + break; + case 1 << 2: + snprintf(buf, maxlen, "Open-Driving"); + break; + case 1 << 3: + snprintf(buf, maxlen, "Open-Fault"); + break; + case 1 << 4: + snprintf(buf, maxlen, "Closed-Fault"); + break; + default: + snprintf(buf, maxlen, "Open(rsvd)"); + break; + } - /* XXX Fuel system 2 status */ + /* XXX Fuel system 2 status */ } - static void -format_data(char *buf, int maxlen, int english, const struct pid *p, response *data, int n) { - double v; +format_data(char *buf, int maxlen, int english, const struct pid *p, response *data, + int n) { + double v; - v = DATA_SCALED(p, DATA_RAW(p, n, data)); - if (english && p->fmt2) { - snprintf(buf, maxlen, p->fmt2, DATA_ENGLISH(p, v)); - } else { - snprintf(buf, maxlen, p->fmt1, v); - } + v = DATA_SCALED(p, DATA_RAW(p, n, data)); + if (english && p->fmt2) { + snprintf(buf, maxlen, p->fmt2, DATA_ENGLISH(p, v)); + } else { + snprintf(buf, maxlen, p->fmt1, v); + } } - /* conversion factors from the "units" package */ static const struct pid pids[] = { - {0x03, "Fuel System Status", format_fuel, 2, - "", 0.0, 0.0, - "", 0.0, 0.0}, - {0x04, "Calculated Load Value", format_data, 1, - "%5.1f%%", (100.0/255), 0.0, - "", 0.0, 0.0}, - {0x05, "Engine Coolant Temperature", format_data, 1, - "%3.0fC", 1, -40, - "%3.0fF", 1.8, 32}, - {0x06, "Short term fuel trim Bank 1", format_data, 1, - "%5.1f%%", (100.0/128), -100, - "", 0.0, 0.0}, - {0x07, "Long term fuel trim Bank 1", format_data, 1, - "%5.1f%%", (100.0/128), -100, - "", 0.0, 0.0}, - {0x08, "Short term fuel trim Bank 2", format_data, 1, - "%5.1f%%", (100.0/128), -100, - "", 0.0, 0.0}, - {0x09, "Long term fuel trim Bank 2", format_data, 1, - "%5.1f%%", (100.0/128), -100, - "", 0.0, 0.0}, - {0x0a, "Fuel Pressure", format_data, 1, - "%3.0fkPaG", 3.0, 0.0, - "%4.1fpsig", 0.14503774, 0.0}, - {0x0b, "Intake Manifold Pressure", format_data, 1, - "%3.0fkPaA", 1.0, 0.0, - "%4.1finHg", 0.29529983, 0.0}, - {0x0c, "Engine RPM", format_data, 2, - "%5.0fRPM", 0.25, 0.0, - "", 0.0, 0.0}, - {0x0d, "Vehicle Speed", format_data, 1, - "%3.0fkm/h", 1.0, 0.0, - "%3.0fmph", 0.62137119, 0.0}, - {0x0e, "Ignition timing advance Cyl #1", format_data, 1, - "%4.1f deg", 0.5, -64.0, - "", 0.0, 0.0}, - {0x0f, "Intake Air Temperature", format_data, 1, - "%3.0fC", 1.0, -40.0, - "%3.0fF", 1.8, 32.0}, - {0x10, "Air Flow Rate", format_data, 2, - "%6.2fgm/s", 0.01, 0.0, - "%6.1flb/min", 0.13227736, 0.0}, - {0x11, "Absolute Throttle Position", format_data, 1, - "%5.1f%%", (100.0/255), 0.0, - "", 0.0, 0.0}, - {0x12, "Commanded Secondary Air Status", format_data, 1, - "", 0, 0, - "", 0, 0}, //can't format bit fields - {0x13, "Location of Oxygen Sensors", format_data, 1, - "", 0, 0, - "", 0, 0}, //can't format bit fields - {0x14, "Bank 1 Sensor 1 Voltage/Trim", format_o2, 2, - "%5.3fV", 0.005, 0.0, - "%5.3fV/%5.1f%%", (100.0/128), -100.0}, - {0x15, "Bank 1 Sensor 2 Voltage/Trim", format_o2, 2, - "%5.3fV", 0.005, 0.0, - "%5.3fV/%5.1f%%", (100.0/128), -100.0}, - {0x16, "Bank 1 Sensor 3 Voltage/Trim", format_o2, 2, - "%5.3fV", 0.005, 0.0, - "%5.3fV/%5.1f%%", (100.0/128), -100.0}, - {0x17, "Bank 1 Sensor 4 Voltage/Trim", format_o2, 2, - "%5.3fV", 0.005, 0.0, - "%5.3fV/%5.1f%%", (100.0/128), -100.0}, - {0x18, "Bank 2 Sensor 1 Voltage/Trim", format_o2, 2, - "%5.3fV", 0.005, 0.0, - "%5.3fV/%5.1f%%", (100.0/128), -100.0}, - {0x19, "Bank 2 Sensor 2 Voltage/Trim", format_o2, 2, - "%5.3fV", 0.005, 0.0, - "%5.3fV/%5.1f%%", (100.0/128), -100.0}, - {0x1a, "Bank 2 Sensor 3 Voltage/Trim", format_o2, 2, - "%5.3fV", 0.005, 0.0, - "%5.3fV/%5.1f%%", (100.0/128), -100.0}, - {0x1b, "Bank 2 Sensor 4 Voltage/Trim", format_o2, 2, - "%5.3fV", 0.005, 0.0, - "%5.3fV/%5.1f%%", (100.0/128), -100.0}, - {0x1e, "Auxiliary Input Status", format_aux, 1, - "", 0.0, 0.0, - "", 0.0, 0.0}, + {0x03, "Fuel System Status", format_fuel, 2, "", 0.0, 0.0, "", 0.0, 0.0}, + {0x04, "Calculated Load Value", format_data, 1, "%5.1f%%", (100.0 / 255), 0.0, "", + 0.0, 0.0}, + {0x05, "Engine Coolant Temperature", format_data, 1, "%3.0fC", 1, -40, "%3.0fF", + 1.8, 32}, + {0x06, "Short term fuel trim Bank 1", format_data, 1, "%5.1f%%", (100.0 / 128), + -100, "", 0.0, 0.0}, + {0x07, "Long term fuel trim Bank 1", format_data, 1, "%5.1f%%", (100.0 / 128), + -100, "", 0.0, 0.0}, + {0x08, "Short term fuel trim Bank 2", format_data, 1, "%5.1f%%", (100.0 / 128), + -100, "", 0.0, 0.0}, + {0x09, "Long term fuel trim Bank 2", format_data, 1, "%5.1f%%", (100.0 / 128), + -100, "", 0.0, 0.0}, + {0x0a, "Fuel Pressure", format_data, 1, "%3.0fkPaG", 3.0, 0.0, "%4.1fpsig", + 0.14503774, 0.0}, + {0x0b, "Intake Manifold Pressure", format_data, 1, "%3.0fkPaA", 1.0, 0.0, + "%4.1finHg", 0.29529983, 0.0}, + {0x0c, "Engine RPM", format_data, 2, "%5.0fRPM", 0.25, 0.0, "", 0.0, 0.0}, + {0x0d, "Vehicle Speed", format_data, 1, "%3.0fkm/h", 1.0, 0.0, "%3.0fmph", + 0.62137119, 0.0}, + {0x0e, "Ignition timing advance Cyl #1", format_data, 1, "%4.1f deg", 0.5, -64.0, + "", 0.0, 0.0}, + {0x0f, "Intake Air Temperature", format_data, 1, "%3.0fC", 1.0, -40.0, "%3.0fF", + 1.8, 32.0}, + {0x10, "Air Flow Rate", format_data, 2, "%6.2fgm/s", 0.01, 0.0, "%6.1flb/min", + 0.13227736, 0.0}, + {0x11, "Absolute Throttle Position", format_data, 1, "%5.1f%%", (100.0 / 255), 0.0, + "", 0.0, 0.0}, + {0x12, "Commanded Secondary Air Status", format_data, 1, "", 0, 0, "", 0, + 0}, // can't format bit fields + {0x13, "Location of Oxygen Sensors", format_data, 1, "", 0, 0, "", 0, 0}, // can't + // format + // bit + // fields + {0x14, "Bank 1 Sensor 1 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0.0, + "%5.3fV/%5.1f%%", (100.0 / 128), -100.0}, + {0x15, "Bank 1 Sensor 2 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0.0, + "%5.3fV/%5.1f%%", (100.0 / 128), -100.0}, + {0x16, "Bank 1 Sensor 3 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0.0, + "%5.3fV/%5.1f%%", (100.0 / 128), -100.0}, + {0x17, "Bank 1 Sensor 4 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0.0, + "%5.3fV/%5.1f%%", (100.0 / 128), -100.0}, + {0x18, "Bank 2 Sensor 1 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0.0, + "%5.3fV/%5.1f%%", (100.0 / 128), -100.0}, + {0x19, "Bank 2 Sensor 2 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0.0, + "%5.3fV/%5.1f%%", (100.0 / 128), -100.0}, + {0x1a, "Bank 2 Sensor 3 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0.0, + "%5.3fV/%5.1f%%", (100.0 / 128), -100.0}, + {0x1b, "Bank 2 Sensor 4 Voltage/Trim", format_o2, 2, "%5.3fV", 0.005, 0.0, + "%5.3fV/%5.1f%%", (100.0 / 128), -100.0}, + {0x1e, "Auxiliary Input Status", format_aux, 1, "", 0.0, 0.0, "", 0.0, 0.0}, }; - -const struct pid *get_pid ( unsigned int i ) { +const struct pid * +get_pid(unsigned int i) { if (i >= ARRAY_SIZE(pids)) { return NULL; } - return & pids[i] ; + return &pids[i]; } - /* * Main */ int main(int argc, char **argv) { - int user_interface = 1 ; - int i ; - const char *startfile=NULL; /* optional commands to run at startup */ - - for ( i = 1 ; i < argc ; i++ ) { - if ( argv[i][0] == '-' || argv[i][0] == '+' ) { - switch ( argv[i][1] ) { - case 'c' : user_interface = 1 ; break ; - case 'a' : user_interface = 0 ; break ; - case 'f' : + int user_interface = 1; + int i; + const char *startfile = NULL; /* optional commands to run at startup */ + + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-' || argv[i][0] == '+') { + switch (argv[i][1]) { + case 'c': + user_interface = 1; + break; + case 'a': + user_interface = 0; + break; + case 'f': user_interface = 1; i++; if (i < argc) { @@ -1765,18 +1744,22 @@ main(int argc, char **argv) { exit(1); } break; - case 'h' : do_usage() ; exit(0 ) ; - default : do_usage() ; exit(1) ; + case 'h': + do_usage(); + exit(0); + default: + do_usage(); + exit(1); } } else { - do_usage() ; - exit(1) ; + do_usage(); + exit(1); } } do_init(); - if ( user_interface ) { + if (user_interface) { printf("%s version %s\n", PROJECT_NAME, PACKAGE_VERSION); enter_cli(SCANTOOL_PROGNAME, startfile, scantool_cmd_table); } else { @@ -1786,4 +1769,3 @@ main(int argc, char **argv) { /* Done */ exit(0); } - diff --git a/scantool/scantool.h b/scantool/scantool.h index 03c48604..faafae70 100644 --- a/scantool/scantool.h +++ b/scantool/scantool.h @@ -39,18 +39,17 @@ extern "C" { #endif - /* Structure to hold responses */ typedef struct { - uint8_t type; - uint8_t len; - uint8_t data[7]; + uint8_t type; + uint8_t len; + uint8_t data[7]; } response; -#define TYPE_UNTESTED 0 /* unchecked, prob because ECU doesn't support */ -#define TYPE_FAILED 1 /* Got failure response */ -#define TYPE_GOOD 2 /* Valid info */ +#define TYPE_UNTESTED 0 /* unchecked, prob because ECU doesn't support */ +#define TYPE_FAILED 1 /* Got failure response */ +#define TYPE_GOOD 2 /* Valid info */ /* * This structure holds all the data/config info for a given ecu @@ -58,37 +57,38 @@ typedef struct { * the data is stored in this */ typedef struct { - uint8_t valid; /* Valid flag */ - uint8_t ecu_addr; /* Address */ + uint8_t valid; /* Valid flag */ + uint8_t ecu_addr; /* Address */ - uint8_t supress; /* Supress output of data from ECU in monitor mode; not implemented*/ + uint8_t supress; /* Supress output of data from ECU in monitor mode; not + implemented*/ - uint8_t mode1_info[0x100]; /* Pids supported by ECU */ - uint8_t mode2_info[0x100]; /* Freeze frame version */ - uint8_t mode5_info[0x100]; /* Mode 5 info */ - uint8_t mode6_info[0x100]; /* Mode 6 info */ - uint8_t mode8_info[0x100]; /* Mode 8 info */ - uint8_t mode9_info[0x100]; /* Mode 9 info */ + uint8_t mode1_info[0x100]; /* Pids supported by ECU */ + uint8_t mode2_info[0x100]; /* Freeze frame version */ + uint8_t mode5_info[0x100]; /* Mode 5 info */ + uint8_t mode6_info[0x100]; /* Mode 6 info */ + uint8_t mode8_info[0x100]; /* Mode 8 info */ + uint8_t mode9_info[0x100]; /* Mode 9 info */ - uint8_t data_good; /* Flags for above data */ + uint8_t data_good; /* Flags for above data */ - uint8_t O2_sensors; /* O2 sensors bit mask */ + uint8_t O2_sensors; /* O2 sensors bit mask */ - response mode1_data[256]; /* Response data for all responses */ - response mode2_data[256]; /* Same, but for freeze frame */ + response mode1_data[256]; /* Response data for all responses */ + response mode2_data[256]; /* Same, but for freeze frame */ - struct diag_msg *rxmsg; /* Received message */ + struct diag_msg *rxmsg; /* Received message */ } ecu_data; -#define ECU_DATA_PIDS 0x01 -#define ECU_DATA_MODE2 0x02 -#define ECU_DATA_MODE5 0x04 -#define ECU_DATA_MODE6 0x08 -#define ECU_DATA_MODE8 0x10 -#define ECU_DATA_MODE9 0x20 +#define ECU_DATA_PIDS 0x01 +#define ECU_DATA_MODE2 0x02 +#define ECU_DATA_MODE5 0x04 +#define ECU_DATA_MODE6 0x08 +#define ECU_DATA_MODE8 0x10 +#define ECU_DATA_MODE9 0x20 -#define MAX_ECU 8 /* Max 8 Ecus responding */ -extern ecu_data ecu_info[MAX_ECU]; +#define MAX_ECU 8 /* Max 8 Ecus responding */ +extern ecu_data ecu_info[MAX_ECU]; extern unsigned int ecu_count; struct diag_l2_conn; @@ -99,18 +99,18 @@ struct diag_l3_conn; * J1979 messages are 7 data bytes long: mode(SID) byte + max 6 extra bytes * (J1979 5.3.2; table 8) * @return 0 if ok -*/ + */ int l3_do_j1979_rqst(struct diag_l3_conn *d_conn, uint8_t mode, uint8_t p1, uint8_t p2, - uint8_t p3, uint8_t p4, uint8_t p5, uint8_t p6, void *handle); + uint8_t p3, uint8_t p4, uint8_t p5, uint8_t p6, void *handle); /* * Send some data on the connection */ -int l3_do_send( struct diag_l3_conn *d_conn, void *data, size_t len, void *handle); -int l2_do_send( struct diag_l2_conn *d_conn, void *data, size_t len, void *handle); +int l3_do_send(struct diag_l3_conn *d_conn, void *data, size_t len, void *handle); +int l2_do_send(struct diag_l2_conn *d_conn, void *data, size_t len, void *handle); int l2_check_pid_bits(uint8_t *data, int pid); -int do_l2_9141_start(int destaddr); // 9141 init -int do_l2_14230_start(int init_type); //14230 init +int do_l2_9141_start(int destaddr); // 9141 init +int do_l2_14230_start(int init_type); // 14230 init int do_j1979_getdtcs(void); int do_j1979_getO2sensors(void); int diag_cleardtc(void); @@ -124,23 +124,23 @@ struct diag_msg *find_ecu_msg(int byte, databyte_type val); * Now they are rather declared as const ints so we can pass * pointers to that instead of masquerading ints as void pointers. */ -#define RQST_HANDLE_NORMAL 0 /* Normal mode */ -#define RQST_HANDLE_WATCH 1 /* Watching, add timestamp */ -#define RQST_HANDLE_DECODE 2 /* Just decode what arrived */ -#define RQST_HANDLE_NCMS 3 /* Non cont. mon. tests */ -#define RQST_HANDLE_NCMS2 4 /* Ditto, print fails only */ -#define RQST_HANDLE_O2S 5 /* O2 sensor tests */ -#define RQST_HANDLE_READINESS 6 /* Readiness Tests */ -extern const int _RQST_HANDLE_NORMAL; //Normal mode -extern const int _RQST_HANDLE_WATCH; //Watching; add timestamp -extern const int _RQST_HANDLE_DECODE; //Just decode what arrived -extern const int _RQST_HANDLE_NCMS; //Non cont. mon. tests -extern const int _RQST_HANDLE_NCMS2; //Ditto; print fails only -extern const int _RQST_HANDLE_O2S; //O2 sensor tests -extern const int _RQST_HANDLE_READINESS; //Readiness tests +#define RQST_HANDLE_NORMAL 0 /* Normal mode */ +#define RQST_HANDLE_WATCH 1 /* Watching, add timestamp */ +#define RQST_HANDLE_DECODE 2 /* Just decode what arrived */ +#define RQST_HANDLE_NCMS 3 /* Non cont. mon. tests */ +#define RQST_HANDLE_NCMS2 4 /* Ditto, print fails only */ +#define RQST_HANDLE_O2S 5 /* O2 sensor tests */ +#define RQST_HANDLE_READINESS 6 /* Readiness Tests */ +extern const int _RQST_HANDLE_NORMAL; // Normal mode +extern const int _RQST_HANDLE_WATCH; // Watching; add timestamp +extern const int _RQST_HANDLE_DECODE; // Just decode what arrived +extern const int _RQST_HANDLE_NCMS; // Non cont. mon. tests +extern const int _RQST_HANDLE_NCMS2; // Ditto; print fails only +extern const int _RQST_HANDLE_O2S; // O2 sensor tests +extern const int _RQST_HANDLE_READINESS; // Readiness tests int do_j1979_getdata(int interruptible_flag); -void do_j1979_basics(void) ; +void do_j1979_basics(void); void do_j1979_cms(void); void do_j1979_ncms(int); void do_j1979_getpids(void); @@ -150,43 +150,41 @@ void do_j1979_getO2tests(int O2sensor); /* * Receive callback routines for various L3/L2 types */ -void j1979_data_rcv(void *handle, struct diag_msg *msg); -void j1979_watch_rcv(void *handle, struct diag_msg *msg); -void l2raw_data_rcv(void *handle, struct diag_msg *msg); - - +void j1979_data_rcv(void *handle, struct diag_msg *msg); +void j1979_watch_rcv(void *handle, struct diag_msg *msg); +void l2raw_data_rcv(void *handle, struct diag_msg *msg); /** J1979 PID structures + utils **/ -struct pid ; +struct pid; /* format bytes of data into buf, up to chars. */ -typedef void (formatter)(char *buf, int maxlen, int units, const struct pid *, response *, int numbytes); +typedef void(formatter)(char *buf, int maxlen, int units, const struct pid *, response *, + int numbytes); struct pid { - int pidID ; - const char *desc ; - formatter *cust_snprintf ; - int bytes ; - const char *fmt1 ; // SI - double scale1 ; - double offset1 ; - const char *fmt2 ; // English (typically) - double scale2 ; - double offset2 ; + int pidID; + const char *desc; + formatter *cust_snprintf; + int bytes; + const char *fmt1; // SI + double scale1; + double offset1; + const char *fmt2; // English (typically) + double scale2; + double offset2; }; -#define DATA_VALID(p, d) (d[p->pidID].type == TYPE_GOOD) -#define DATA_1(p, n, d) (d[p->pidID].data[n]) /* extract 8bit value @offset n */ -#define DATA_2(p, n, d) (DATA_1(p, n, d) * 256 + DATA_1(p, n+1, d)) /* extract 16bit value @offset n */ -#define DATA_RAW(p, n, d) (p->bytes == 1 ? DATA_1(p, n, d) : DATA_2(p, n, d)) +#define DATA_VALID(p, d) (d[p->pidID].type == TYPE_GOOD) +#define DATA_1(p, n, d) (d[p->pidID].data[n]) /* extract 8bit value @offset n */ +#define DATA_2(p, n, d) \ + (DATA_1(p, n, d) * 256 + DATA_1(p, n + 1, d)) /* extract 16bit value @offset n */ +#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) - - -const struct pid *get_pid ( unsigned int i ) ; +#define DATA_SCALED(p, v) (v * p->scale1 + p->offset1) +#define DATA_ENGLISH(p, v) (v * p->scale2 + p->offset2) +const struct pid *get_pid(unsigned int i); #if defined(__cplusplus) } -#endif +# endif #endif /* _SCANTOOL_H_ */ diff --git a/scantool/scantool_850.c b/scantool/scantool_850.c index 5b298d0a..ae099464 100644 --- a/scantool/scantool_850.c +++ b/scantool/scantool_850.c @@ -65,8 +65,8 @@ static struct ecu_info ecu_list[] = { {0x10, "m43", "Motronic M4.3 engine management (DLC pin 3)", "EFI"}, /* 12700bps, KWP71 */ #endif {0x10, "m44old", "Motronic M4.4 engine management (old protocol)", "EFI"}, - {0x11, "msa", "MSA 15.7 engine management (diesel vehicles)" ,"EFI"}, - /* 0x13 - Volvo Scan Tool tester address */ + {0x11, "msa", "MSA 15.7 engine management (diesel vehicles)", "EFI"}, +/* 0x13 - Volvo Scan Tool tester address */ #if 0 {0x15, "m18", "Motronic M1.8 engine management (960)", "EFI"}, /* 4800bps, KWP71 */ #endif @@ -81,8 +81,7 @@ static struct ecu_info ecu_list[] = { {0x58, "srs", "airbags", "SRS"}, {0x6e, "aw50", "AW50-42 transmission", "AT"}, {0x7a, "m44", "Motronic M4.4 engine management", "EFI"}, - {0, NULL, NULL, NULL} -}; + {0, NULL, NULL, NULL}}; struct dtc_table_entry { uint8_t ecu_addr; @@ -95,8 +94,7 @@ static struct dtc_table_entry dtc_table[] = { {0x6e, 0x13, 332, "Torque converter lock-up solenoid open circuit"}, {0x10, 0x54, 445, "Pulsed secondary air injection system pump signal"}, {0x7a, 0x54, 445, "Pulsed secondary air injection system pump signal"}, - {0, 0, 0, NULL} -}; + {0, 0, 0, NULL}}; static bool have_read_dtcs = false; static struct diag_msg *ecu_id = NULL; @@ -119,51 +117,42 @@ static int cmd_850_scan_all(int argc, UNUSED(char **argv)); static int cmd_850_test(int argc, char **argv); const struct cmd_tbl_entry v850_cmd_table[] = { - { "help", "help [command]", "Gives help for a command", - cmd_850_help, 0, NULL}, - { "?", "? [command]", "Gives help for a command", - cmd_850_help, 0, NULL}, - - { "connect", "connect ", "Connect to ECU. Use '850 connect ?' to show ECU names.", - cmd_850_connect, 0, NULL}, - { "disconnect", "disconnect", "Disconnect from ECU", - cmd_850_disconnect, 0, NULL}, - { "scan-all", "scan-all", "Try connecting to all possible ECUs, print identification and DTCs", - cmd_850_scan_all, 0, NULL}, - { "sendreq", "sendreq ", "Send raw data to the ECU and print response", - cmd_850_sendreq, 0, NULL}, - { "ping", "ping", "Verify communication with the ECU", cmd_850_ping, - 0, NULL}, - { "peek", "peek [w|l][.addr2] [addr2 ...] [live]", "Display contents of RAM, once or continuously", - cmd_850_peek, 0, NULL}, - { "dumpram", "dumpram [fast]", "Dump entire RAM contents to file (Warning: takes 20+ minutes)", - cmd_850_dumpram, 0, NULL}, - { "read", "read |* [id2 ...] [live]", "Display live data, once or continuously", - cmd_850_read, 0, NULL}, - { "adc", "adc id1 [id2 ...]", "Display ADC readings, once or continuously", - cmd_850_adc, 0, NULL}, - { "readnv", "readnv id1 [id2 ...]", "Display non-volatile data", - cmd_850_readnv, 0, NULL}, - { "id", "id", "Display ECU identification", - cmd_850_id, 0, NULL}, - { "dtc", "dtc", "Retrieve DTCs", - cmd_850_dtc, 0, NULL}, - { "cleardtc", "cleardtc", "Clear DTCs from ECU", - cmd_850_cleardtc, 0, NULL}, - { "freeze", "freeze dtc1|all [dtc2 ...]", "Display freeze frame(s)", - cmd_850_freeze, 0, NULL}, - { "test", "test ", "Test vehicle components", - cmd_850_test, 0, NULL}, - - { "up", "up", "Return to previous menu level", - cmd_up, 0, NULL}, - { "quit","quit", "Exit program", - cmd_exit, FLAG_HIDDEN, NULL}, - { "exit", "exit", "Exit program", - cmd_exit, 0, NULL}, - - { NULL, NULL, NULL, NULL, 0, NULL} -}; + {"help", "help [command]", "Gives help for a command", cmd_850_help, 0, NULL}, + {"?", "? [command]", "Gives help for a command", cmd_850_help, 0, NULL}, + + {"connect", "connect ", + "Connect to ECU. Use '850 connect ?' to show ECU names.", cmd_850_connect, 0, + NULL}, + {"disconnect", "disconnect", "Disconnect from ECU", cmd_850_disconnect, 0, NULL}, + {"scan-all", "scan-all", + "Try connecting to all possible ECUs, print identification and DTCs", + cmd_850_scan_all, 0, NULL}, + {"sendreq", "sendreq ", + "Send raw data to the ECU and print response", cmd_850_sendreq, 0, NULL}, + {"ping", "ping", "Verify communication with the ECU", cmd_850_ping, 0, NULL}, + {"peek", "peek [w|l][.addr2] [addr2 ...] [live]", + "Display contents of RAM, once or continuously", cmd_850_peek, 0, NULL}, + {"dumpram", "dumpram [fast]", + "Dump entire RAM contents to file (Warning: takes 20+ minutes)", cmd_850_dumpram, + 0, NULL}, + {"read", "read |* [id2 ...] [live]", + "Display live data, once or continuously", cmd_850_read, 0, NULL}, + {"adc", "adc id1 [id2 ...]", "Display ADC readings, once or continuously", + cmd_850_adc, 0, NULL}, + {"readnv", "readnv id1 [id2 ...]", "Display non-volatile data", cmd_850_readnv, 0, + NULL}, + {"id", "id", "Display ECU identification", cmd_850_id, 0, NULL}, + {"dtc", "dtc", "Retrieve DTCs", cmd_850_dtc, 0, NULL}, + {"cleardtc", "cleardtc", "Clear DTCs from ECU", cmd_850_cleardtc, 0, NULL}, + {"freeze", "freeze dtc1|all [dtc2 ...]", "Display freeze frame(s)", cmd_850_freeze, + 0, NULL}, + {"test", "test ", "Test vehicle components", cmd_850_test, 0, NULL}, + + {"up", "up", "Return to previous menu level", cmd_up, 0, NULL}, + {"quit", "quit", "Exit program", cmd_exit, FLAG_HIDDEN, NULL}, + {"exit", "exit", "Exit program", cmd_exit, 0, NULL}, + + {NULL, NULL, NULL, NULL, 0, NULL}}; static int cmd_850_help(int argc, char **argv) { @@ -179,7 +168,7 @@ capitalize(const char *in) { static char buf[80]; strncpy(buf, in, sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; + buf[sizeof(buf) - 1] = '\0'; if (isalpha(buf[0]) && islower(buf[0])) { buf[0] = toupper(buf[0]); @@ -275,8 +264,8 @@ current_ecu_desc(void) { */ static char * dtc_printable_by_raw(uint8_t addr, uint8_t raw, char **desc) { - static char printable[7+1]; - static char *empty=""; + static char printable[7 + 1]; + static char *empty = ""; struct ecu_info *ecu_entry; struct dtc_table_entry *dtc_entry; char *prefix; @@ -367,8 +356,7 @@ dtc_raw_by_printable(char *printable) { /* find suffix */ ecu_addr = global_l2_conn->diag_l2_destaddr; for (dtc_entry = dtc_table; dtc_entry->dtc_suffix != 0; dtc_entry++) { - if (dtc_entry->ecu_addr == ecu_addr && - dtc_entry->dtc_suffix == suffix) { + if (dtc_entry->ecu_addr == ecu_addr && dtc_entry->dtc_suffix == suffix) { return dtc_entry->raw_value; } } @@ -389,11 +377,11 @@ print_ecu_list(void) { } enum connection_status { - NOT_CONNECTED, /* Not connected */ - CONNECTED_D2, /* Connected with D2 over K-line */ - CONNECTED_KWP71, /* Connected with KWP71 */ - CONNECTED_EITHER, /* Connected with either D2 or KWP71 */ - CONNECTED_OTHER /* Connected with non-Volvo protocol */ + NOT_CONNECTED, /* Not connected */ + CONNECTED_D2, /* Connected with D2 over K-line */ + CONNECTED_KWP71, /* Connected with KWP71 */ + CONNECTED_EITHER, /* Connected with either D2 or KWP71 */ + CONNECTED_OTHER /* Connected with non-Volvo protocol */ }; /* @@ -420,8 +408,8 @@ get_connection_status(void) { static bool valid_arg_count(int min, int argc, int max) { if (argc < min) { - printf("Too few arguments\n"); - return false; + printf("Too few arguments\n"); + return false; } if (argc > max) { @@ -453,7 +441,8 @@ valid_connection_status(unsigned int want) { return false; case CONNECTED_OTHER: if (want == NOT_CONNECTED) { - printf("Already connected with non-Volvo protocol. Please use 'diag disconnect'.\n"); + printf("Already connected with non-Volvo protocol. Please use " + "'diag disconnect'.\n"); } else { printf("Connected with non-Volvo protocol.\n"); } @@ -461,7 +450,8 @@ valid_connection_status(unsigned int want) { case CONNECTED_D2: case CONNECTED_KWP71: if (want == NOT_CONNECTED) { - printf("Already connected to %s. Please disconnect first.\n", current_ecu_desc()); + printf("Already connected to %s. Please disconnect first.\n", + current_ecu_desc()); } else { printf("This function is not available with this protocol.\n"); } @@ -480,7 +470,7 @@ static void adaptive_timing_workaround(void) { int i; - for (i=0;i<3;i++) { + for (i = 0; i < 3; i++) { (void)diag_l7_d2_ping(global_l2_conn); diag_os_millisleep(200); } @@ -561,9 +551,9 @@ cmd_850_connect(int argc, char **argv) { return diag_iseterr(rv); } - global_l2_conn = diag_l2_StartCommunications(dl0d, global_cfg.L2proto, - global_cfg.initmode & DIAG_L2_TYPE_INITMASK, global_cfg.speed, - global_cfg.tgt, global_cfg.src); + global_l2_conn = diag_l2_StartCommunications( + dl0d, global_cfg.L2proto, global_cfg.initmode & DIAG_L2_TYPE_INITMASK, + global_cfg.speed, global_cfg.tgt, global_cfg.src); if (global_l2_conn == NULL) { rv = diag_geterr(); diag_l2_close(dl0d); @@ -571,9 +561,13 @@ cmd_850_connect(int argc, char **argv) { } if (global_cfg.L2proto == DIAG_L2_PROT_VAG) { - (void)diag_l2_ioctl(global_l2_conn, DIAG_IOCTL_GET_L2_DATA, (void *)&l2data); - if (l2data.kb1!=0xab || l2data.kb2!=0x02) { - fprintf(stderr, FLFMT "_connect : wrong keybytes %02X%02X, expecting AB02\n", FL, l2data.kb1, l2data.kb2); + (void)diag_l2_ioctl(global_l2_conn, DIAG_IOCTL_GET_L2_DATA, + (void *)&l2data); + if (l2data.kb1 != 0xab || l2data.kb2 != 0x02) { + fprintf(stderr, + FLFMT + "_connect : wrong keybytes %02X%02X, expecting AB02\n", + FL, l2data.kb1, l2data.kb2); diag_l2_StopCommunications(global_l2_conn); diag_l2_close(dl0d); global_l2_conn = NULL; @@ -658,11 +652,10 @@ cmd_850_sendreq(int argc, char **argv) { len = argc - 1; for (i = 0; i < len; i++) { - data[i] = (uint8_t) htoi(argv[i+1]); + data[i] = (uint8_t)htoi(argv[i + 1]); } - rv = l2_do_send( global_l2_conn, data, len, - (void *)&_RQST_HANDLE_DECODE); + rv = l2_do_send(global_l2_conn, data, len, (void *)&_RQST_HANDLE_DECODE); if (rv == DIAG_ERR_TIMEOUT) { printf("No data received\n"); @@ -709,16 +702,21 @@ cmd_850_ping(int argc, UNUSED(char **argv)) { */ static void interpret_value(enum namespace ns, uint16_t addr, UNUSED(int len), uint8_t *buf) { - if (ns==NS_LIVEDATA && addr==0x0200) { - printf("Engine Coolant Temperature: %dC (%dF)\n", buf[1]-80, (buf[1]-80)*9/5+32); - } else if (ns==NS_LIVEDATA && addr==0x0300) { + if (ns == NS_LIVEDATA && addr == 0x0200) { + printf("Engine Coolant Temperature: %dC (%dF)\n", buf[1] - 80, + (buf[1] - 80) * 9 / 5 + 32); + } else if (ns == NS_LIVEDATA && addr == 0x0300) { /*ECU pin A27, MCU P7.1 input, divider ratio 8250/29750, 5Vref*/ - printf("Battery voltage: %.1f V\n", (float)buf[0]*29750/8250*5/256); - } else if (ns==NS_MEMORY && addr==0x36 && global_l2_conn->diag_l2_destaddr==0x10) { - printf("Battery voltage: %.1f V\n", (float)buf[0]*29750/8250*5/256); - } else if (ns==NS_LIVEDATA && addr==0x1000) { + printf("Battery voltage: %.1f V\n", + (float)buf[0] * 29750 / 8250 * 5 / 256); + } else if (ns == NS_MEMORY && addr == 0x36 && + global_l2_conn->diag_l2_destaddr == 0x10) { + printf("Battery voltage: %.1f V\n", + (float)buf[0] * 29750 / 8250 * 5 / 256); + } else if (ns == NS_LIVEDATA && addr == 0x1000) { /* ECU pin A4, MCU P7.4 input, divider ratio 8250/9460 */ - printf("MAF sensor signal: %.2f V\n", (float)buf[0]*9460/8250*5/256); + printf("MAF sensor signal: %.2f V\n", + (float)buf[0] * 9460 / 8250 * 5 / 256); } } @@ -733,8 +731,8 @@ interpret_block(enum namespace ns, uint16_t addr, int len, uint8_t *buf) { addr <<= 8; } - for (i=0; iend = item->start + 3; } else if ((p[0] == '.' || p[0] == '-') && p[1] != '\0') { - item->end = strtoul(p+1, &q, 0); + item->end = strtoul(p + 1, &q, 0); if (*q != '\0' || item->end < item->start) { printf("Invalid address range '%s'\n", arg); return 1; @@ -804,7 +802,7 @@ parse_read_arg(char *arg, struct read_or_peek_item *item) { printf("Invalid identifier '%s'\n", arg); return 1; } - return parse_peek_arg(arg+1, item); + return parse_peek_arg(arg + 1, item); } item->ns = NS_LIVEDATA; @@ -868,16 +866,19 @@ parse_freeze_arg(char *arg, struct read_or_peek_item *item) { if (*p != '\0' || item->start > 0xff) { printf("Invalid identifier '%s'\n", arg); if (isdigit(arg[0]) && arg[0] != '0' && *p == '\0') { - printf("Did you mean %s-%s?\n", - current_dtc_prefix(), arg); + printf("Did you mean %s-%s?\n", current_dtc_prefix(), arg); } return 1; } - if (isdigit(arg[0]) && arg[0]!='0') { + if (isdigit(arg[0]) && arg[0] != '0') { if (item->start < 100) { - printf("Warning: retrieving freeze frame by raw identifier %d (=%02X).\nDid you mean 0x%s?\n", item->start, item->start, arg); + printf("Warning: retrieving freeze frame by raw identifier %d " + "(=%02X).\nDid you mean 0x%s?\n", + item->start, item->start, arg); } else { - printf("Warning: retrieving freeze frame by raw identifier %d (=%02X).\nDid you mean %s-%s?\n", item->start, item->start, current_dtc_prefix(), arg); + printf("Warning: retrieving freeze frame by raw identifier %d " + "(=%02X).\nDid you mean %s-%s?\n", + item->start, item->start, current_dtc_prefix(), arg); } } return 0; @@ -907,7 +908,7 @@ read_family(int argc, char **argv, enum namespace ns) { continuous = false; count = argc - 1; - if (ns!=NS_NV && ns!=NS_FREEZE && strcasecmp(argv[argc-1], "live")==0) { + if (ns != NS_NV && ns != NS_FREEZE && strcasecmp(argv[argc - 1], "live") == 0) { continuous = true; count--; if (count < 1) { @@ -920,7 +921,7 @@ read_family(int argc, char **argv, enum namespace ns) { return diag_iseterr(rv); } - for (i=0; idiag_l2_destaddr, + global_l2_conn->diag_l2_destaddr, addr, NULL)); } if (gotbytes == 0) { printf("%02X: no data\n", addr); } else if ((unsigned int)gotbytes > sizeof(buf)) { - print_hexdump_line(stdout, addr, 2, buf, sizeof(buf)); - printf(" (%d bytes received, only first %zu shown)\n", gotbytes, sizeof(buf)); - interpret_block(items[i].ns, addr, sizeof(buf), buf); + print_hexdump_line(stdout, addr, 2, buf, + sizeof(buf)); + printf(" (%d bytes received, only first %zu " + "shown)\n", + gotbytes, sizeof(buf)); + interpret_block(items[i].ns, addr, sizeof(buf), + buf); } else { print_hexdump_line(stdout, addr, 2, buf, gotbytes); interpret_block(items[i].ns, addr, gotbytes, buf); @@ -989,18 +997,26 @@ read_family(int argc, char **argv, enum namespace ns) { len = (items[i].end - items[i].start) + 1; while (len > 0) { if (get_connection_status() == CONNECTED_D2) { - gotbytes = diag_l7_d2_read(global_l2_conn, NS_MEMORY, addr, (len<8)?len:8, buf); + gotbytes = diag_l7_d2_read( + global_l2_conn, NS_MEMORY, addr, + (len < 8) ? len : 8, buf); } else { - gotbytes = diag_l7_kwp71_read(global_l2_conn, NS_MEMORY, addr, (len<8)?len:8, buf); + gotbytes = diag_l7_kwp71_read( + global_l2_conn, NS_MEMORY, addr, + (len < 8) ? len : 8, buf); } - if (gotbytes == ((len<8)?len:8)) { - print_hexdump_line(stdout, addr, 4, buf, (len<8)?len:8); - interpret_block(NS_MEMORY, addr, (len<8)?len:8, buf); + if (gotbytes == ((len < 8) ? len : 8)) { + print_hexdump_line(stdout, addr, 4, buf, + (len < 8) ? len : 8); + interpret_block(NS_MEMORY, addr, + (len < 8) ? len : 8, buf); } else { - printf("Error reading %s%04X\n", (ns==NS_LIVEDATA)?"*":"", addr); + printf("Error reading %s%04X\n", + (ns == NS_LIVEDATA) ? "*" : "", + addr); goto done; } - len -= (len<8)?len:8; + len -= (len < 8) ? len : 8; addr += 8; } } @@ -1068,7 +1084,6 @@ cmd_850_adc(int argc, char **argv) { return read_family(argc, argv, NS_ADC); } - /* * Read and display one or more non-volatile parameters. * @@ -1118,19 +1133,19 @@ cmd_850_freeze_all(void) { return diag_iseterr(rv); } - rv = diag_calloc(&argvout, count+1); + rv = diag_calloc(&argvout, count + 1); if (rv) { return diag_iseterr(rv); } p = argbuf; - for (i=0; idiag_l2_destaddr == 0x7a) { rv = diag_l7_d2_read(global_l2_conn, NS_NV, 1, sizeof(buf), buf); @@ -1193,16 +1212,18 @@ cmd_850_id_d2(void) { return CMD_OK; } if (rv != 10) { - printf("Identification response was %d bytes, expected %d\n", rv, 10); + printf("Identification response was %d bytes, expected %d\n", rv, + 10); return CMD_OK; } - for (i=0; i<10; i++) { + for (i = 0; i < 10; i++) { if (!isdigit(buf[i])) { printf("Unexpected characters in identification block\n"); return CMD_OK; } } - printf("Order number: %c %.3s %.3s %.3s\n",buf[0], buf+1, buf+4, buf+7); + printf("Order number: %c %.3s %.3s %.3s\n", buf[0], buf + 1, buf + 4, + buf + 7); } return CMD_OK; @@ -1228,20 +1249,21 @@ cmd_850_id_kwp71(void) { return CMD_OK; } - for (i=0; i<10; i++) { + for (i = 0; i < 10; i++) { if (!isdigit(msg->data[i])) { printf("Unexpected characters in identification block\n"); return CMD_OK; } } - printf("Order number: %c %.3s %.3s %.3s\n",msg->data[0], msg->data+1, msg->data+4, msg->data+7); + printf("Order number: %c %.3s %.3s %.3s\n", msg->data[0], msg->data + 1, + msg->data + 4, msg->data + 7); msg = msg->next; if (msg == NULL) { return CMD_OK; } - /* Second block seems to be meaningless, don't print it. */ + /* Second block seems to be meaningless, don't print it. */ #if 0 print_hexdump_line(stdout, msg->type, 2, msg->data, msg->len); #endif @@ -1255,7 +1277,7 @@ cmd_850_id_kwp71(void) { return CMD_OK; } - for (i=0; i<7; i++) { + for (i = 0; i < 7; i++) { if (!isdigit(msg->data[i])) { printf("Unexpected characters in identification block\n"); return CMD_OK; @@ -1343,8 +1365,8 @@ cmd_850_dumpram(int argc, char **argv) { } else { happy = 0; } - if ((addr&0x1f) == 0) { - printf("\r%04X %s", addr, happy?":)":":/"); + if ((addr & 0x1f) == 0) { + printf("\r%04X %s", addr, happy ? ":)" : ":/"); fflush(stdout); } if (addr == 0xfff8) { @@ -1406,8 +1428,9 @@ cmd_850_dtc(int argc, UNUSED(char **argv)) { } printf("Stored DTCs:\n"); - for (i=0; idiag_l2_destaddr, buf[i], &desc); + for (i = 0; i < rv; i += span) { + code = dtc_printable_by_raw(global_l2_conn->diag_l2_destaddr, buf[i], + &desc); printf("%s (%02X) %s\n", code, buf[i], desc); } @@ -1430,23 +1453,28 @@ cmd_850_cleardtc(int argc, UNUSED(char **argv)) { return CMD_OK; } - input = basic_get_input("Are you sure you wish to clear the Diagnostic Trouble Codes (y/n) ? ", stdin); + input = basic_get_input( + "Are you sure you wish to clear the Diagnostic Trouble Codes (y/n) ? ", + stdin); if (!input) { return CMD_OK; } - if ((strcasecmp(input, "yes") != 0) && (strcasecmp(input, "y")!=0)) { + if ((strcasecmp(input, "yes") != 0) && (strcasecmp(input, "y") != 0)) { printf("Not done\n"); goto done; } if (!have_read_dtcs) { free(input); - input = basic_get_input("You haven't read the DTCs yet. Are you sure you wish to clear them (y/n) ? ", stdin); + input = basic_get_input( + "You haven't read the DTCs yet. Are you sure you wish to clear " + "them (y/n) ? ", + stdin); if (!input) { return CMD_OK; } - if ((strcasecmp(input, "yes") != 0) && (strcasecmp(input, "y")!=0)) { + if ((strcasecmp(input, "yes") != 0) && (strcasecmp(input, "y") != 0)) { printf("Not done\n"); goto done; } @@ -1524,13 +1552,15 @@ cmd_850_test(int argc, char **argv) { return CMD_OK; } - if (argc==2 && strcasecmp(argv[1], "fan1")==0 && global_l2_conn->diag_l2_destaddr==0x7a) { + if (argc == 2 && strcasecmp(argv[1], "fan1") == 0 && + global_l2_conn->diag_l2_destaddr == 0x7a) { if (diag_l7_d2_io_control(global_l2_conn, 0x0e, 3) == 0) { printf("Activating engine cooling fan.\n"); } else { printf("Unable to activate fan.\n"); } - } else if (argc==2 && strcasecmp(argv[1], "fan2")==0 && global_l2_conn->diag_l2_destaddr==0x7a) { + } else if (argc == 2 && strcasecmp(argv[1], "fan2") == 0 && + global_l2_conn->diag_l2_destaddr == 0x7a) { if (diag_l7_d2_io_control(global_l2_conn, 0x1f, 3) == 0) { printf("Activating engine cooling fan.\n"); } else { @@ -1540,8 +1570,10 @@ cmd_850_test(int argc, char **argv) { printf("Usage: test \n"); if (global_l2_conn->diag_l2_destaddr == 0x7a) { printf("Available tests:\n"); - printf("fan1 - Activate engine cooling fan, half speed (please keep fingers clear)\n"); - printf("fan2 - Activate engine cooling fan, full speed (please keep fingers clear)\n"); + printf("fan1 - Activate engine cooling fan, half speed (please " + "keep fingers clear)\n"); + printf("fan2 - Activate engine cooling fan, full speed (please " + "keep fingers clear)\n"); } else { printf("No available tests for this ECU.\n"); } diff --git a/scantool/scantool_aif.c b/scantool/scantool_aif.c index 42ea2356..196e1fdd 100644 --- a/scantool/scantool_aif.c +++ b/scantool/scantool_aif.c @@ -43,206 +43,236 @@ #include "freediag_aif.h" #include "utlist.h" -static void do_aif_command (void) ; -static int debugging = 0 ; +static void do_aif_command(void); +static int debugging = 0; -static void toApp (char command) { - putc(command, stdout) ; +static void +toApp(char command) { + putc(command, stdout); } -static void OkToApp (void) { toApp(FREEDIAG_AIF_OK_RETURN) ; } -static void BadToApp(void) { toApp(FREEDIAG_AIF_ERROR_RETURN) ; } - +static void +OkToApp(void) { + toApp(FREEDIAG_AIF_OK_RETURN); +} +static void +BadToApp(void) { + toApp(FREEDIAG_AIF_ERROR_RETURN); +} /* Remove the 'BadToApp()' function call when you get these working! */ -static void aif_watch(void *data) { (void) data; BadToApp() ; } -static void aif_clear_dtc(void *data) { (void) data; BadToApp() ; } -static void aif_ecus(void *data) {(void) data; BadToApp() ; } -static void aif_test(void *data) { (void) data; BadToApp() ; } -static void aif_diag(void *data) { (void) data; BadToApp() ; } -static void aif_vw(void *data) { (void) data; BadToApp() ; } -static void aif_dyno(void *data) { (void) data; BadToApp() ; } - +static void +aif_watch(void *data) { + (void)data; + BadToApp(); +} +static void +aif_clear_dtc(void *data) { + (void)data; + BadToApp(); +} +static void +aif_ecus(void *data) { + (void)data; + BadToApp(); +} +static void +aif_test(void *data) { + (void)data; + BadToApp(); +} +static void +aif_diag(void *data) { + (void)data; + BadToApp(); +} +static void +aif_vw(void *data) { + (void)data; + BadToApp(); +} +static void +aif_dyno(void *data) { + (void)data; + BadToApp(); +} -static void aif_monitor (UNUSED(void *data)) { +static void +aif_monitor(UNUSED(void *data)) { if (global_state < STATE_CONNECTED) { fprintf(stderr, "scantool: Can't monitor - car is not yet connected.\n"); - BadToApp() ; - return ; + BadToApp(); + return; } - OkToApp() ; + OkToApp(); /* - * Now just receive data and send it to the application - * whenever it requests it. - */ + * Now just receive data and send it to the application + * whenever it requests it. + */ while (1) { - unsigned int i ; - int rv = do_j1979_getdata(1) ; - struct diag_l3_conn *d_conn ; - struct diag_msg *msg ; + unsigned int i; + int rv = do_j1979_getdata(1); + struct diag_l3_conn *d_conn; + struct diag_msg *msg; /* New request arrived. */ if (rv) { - unsigned int j ; + unsigned int j; - for (j = 0 ; get_pid(j) != NULL ; j++) { - const struct pid *p = get_pid(j) ; - ecu_data *ep ; - char buf[24] ; + for (j = 0; get_pid(j) != NULL; j++) { + const struct pid *p = get_pid(j); + ecu_data *ep; + char buf[24]; - for (i = 0, ep = ecu_info ; i < ecu_count ; i++, ep++) { + for (i = 0, ep = ecu_info; i < ecu_count; i++, ep++) { if (DATA_VALID(p, ep->mode1_data) || - DATA_VALID(p, ep->mode2_data)) { - if (DATA_VALID( - p, - ep->mode1_data)) { - p->cust_snprintf( - buf, - sizeof(buf), - global_cfg - .units, - p, - ep->mode1_data, - 2); + DATA_VALID(p, ep->mode2_data)) { + if (DATA_VALID(p, ep->mode1_data)) { + p->cust_snprintf(buf, sizeof(buf), + global_cfg.units, + p, ep->mode1_data, + 2); } printf("%-15.15s ", buf); - if (DATA_VALID( - p, - ep->mode2_data)) { - p->cust_snprintf( - buf, - sizeof(buf), - global_cfg - .units, - p, - ep->mode2_data, - 3); + if (DATA_VALID(p, ep->mode2_data)) { + p->cust_snprintf(buf, sizeof(buf), + global_cfg.units, + p, ep->mode2_data, + 3); } printf("%-15.15s\n", buf); } } } - } + } - d_conn = global_l3_conn ; + d_conn = global_l3_conn; - rv = l3_do_j1979_rqst(d_conn, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL) ; + rv = l3_do_j1979_rqst(d_conn, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + (void *)&_RQST_HANDLE_NORMAL); - if (rv == DIAG_ERR_TIMEOUT) { - /* Didn't get a response, this is valid if there are no DTCs */ - } else if (rv != 0) { - fprintf(stderr, "Failed to get test results for" - " continuously monitored systems\n") ; - BadToApp() ; - } else { - /* Currently monitored DTCs: */ + if (rv == DIAG_ERR_TIMEOUT) { + /* Didn't get a response, this is valid if there are no DTCs */ + } else if (rv != 0) { + fprintf(stderr, + "Failed to get test results for" + " continuously monitored systems\n"); + BadToApp(); + } else { + /* Currently monitored DTCs: */ - for (i = 0 ; i < ecu_count ; i++) { - LL_FOREACH(ecu_info[i].rxmsg, msg) { - int i, j ; + for (i = 0; i < ecu_count; i++) { + LL_FOREACH(ecu_info[i].rxmsg, msg) { + int i, j; - for (i = 0, j = 1 ; i < 3 ; i++, j += 2) { - char buf[256]; - uint8_t db[2]; + for (i = 0, j = 1; i < 3; i++, j += 2) { + char buf[256]; + uint8_t db[2]; - if ((msg->data[j] == 0) && - (msg->data[j + 1] == 0)) { - continue; - } + if ((msg->data[j] == 0) && + (msg->data[j + 1] == 0)) { + continue; + } - db[0] = msg->data[j]; - db[1] = msg->data[j+1]; + db[0] = msg->data[j]; + db[1] = msg->data[j + 1]; - diag_dtc_decode(db, 2, NULL, NULL, - dtc_proto_j2012, buf, sizeof(buf)) ; - //what do we do with the decoded DTC ? - //maybe just print it for now... - fprintf(stderr, FLFMT "decoded DTC : %s\n", FL, buf); + diag_dtc_decode(db, 2, NULL, NULL, + dtc_proto_j2012, buf, + sizeof(buf)); + // what do we do with the decoded DTC ? + // maybe just print it for now... + fprintf(stderr, FLFMT "decoded DTC : %s\n", + FL, buf); + } } } - } - } //if DIAG_ERR_TIMEOUT - } //while 1 + } // if DIAG_ERR_TIMEOUT + } // while 1 - OkToApp() ; + OkToApp(); } - -static void aif_set (void *data) { - int sub_command = ((unsigned char *) data)[0] ; +static void +aif_set(void *data) { + int sub_command = ((unsigned char *)data)[0]; switch (sub_command) { - case FREEDIAG_AIF_SET_UNITS : { - int units = ((unsigned char *) data)[1] ; + case FREEDIAG_AIF_SET_UNITS: { + int units = ((unsigned char *)data)[1]; - if (debugging) { - fprintf(stderr, "Setting units to %d\n", units); - } + if (debugging) { + fprintf(stderr, "Setting units to %d\n", units); + } - switch (units) { - case FREEDIAG_AIF_SET_UNITS_US : global_cfg.units = 1 ; break ; - case FREEDIAG_AIF_SET_UNITS_METRIC : global_cfg.units = 0 ; break ; - default : BadToApp() ; return ; - } - break ; + switch (units) { + case FREEDIAG_AIF_SET_UNITS_US: + global_cfg.units = 1; + break; + case FREEDIAG_AIF_SET_UNITS_METRIC: + global_cfg.units = 0; + break; + default: + BadToApp(); + return; } - case FREEDIAG_AIF_SET_PORT : { - int port = ((unsigned char *) data)[1] ; + break; + } + case FREEDIAG_AIF_SET_PORT: { + int port = ((unsigned char *)data)[1]; - if (debugging) { - fprintf(stderr, "Setting port to %d\n", port); - } + if (debugging) { + fprintf(stderr, "Setting port to %d\n", port); + } - if (port < 0 || port > 9) { - BadToApp() ; - return ; - } + if (port < 0 || port > 9) { + BadToApp(); + return; + } - fprintf(stderr, "ERROR - code not complete for CFG rework"); - break ; + fprintf(stderr, "ERROR - code not complete for CFG rework"); + break; + } + default: + if (debugging) { + fprintf(stderr, "Illegal 'Set' command: %d\n", sub_command); } - default : - if (debugging) { - fprintf(stderr, "Illegal 'Set' command: %d\n", - sub_command); - } - BadToApp() ; - return ; + BadToApp(); + return; } - OkToApp() ; + OkToApp(); } - -static void aif_noop (UNUSED(void *data)) { - OkToApp() ; +static void +aif_noop(UNUSED(void *data)) { + OkToApp(); } - -static void aif_exit (UNUSED(void *data)) { - OkToApp() ; - fprintf(stderr, "scantool: Exiting.\n") ; +static void +aif_exit(UNUSED(void *data)) { + OkToApp(); + fprintf(stderr, "scantool: Exiting.\n"); set_close(); - exit (0) ; + exit(0); } - -static void aif_disconnect (UNUSED(void *data)) { +static void +aif_disconnect(UNUSED(void *data)) { if (global_state < STATE_CONNECTED) { - OkToApp() ; - return ; + OkToApp(); + return; } if (global_state >= STATE_L3ADDED) { @@ -256,127 +286,116 @@ static void aif_disconnect (UNUSED(void *data)) { global_l2_conn = NULL; global_state = STATE_IDLE; - OkToApp() ; + OkToApp(); } - - -static void aif_scan (UNUSED(void *data)) { +static void +aif_scan(UNUSED(void *data)) { if (global_state >= STATE_CONNECTED) { - OkToApp() ; - return ; + OkToApp(); + return; } if (ecu_connect() == 0) { - do_j1979_basics () ; /* Ask basic info from ECU */ - do_j1979_cms () ; /* Get test results for monitored systems */ - do_j1979_ncms (0) ; /* And non-continuously monitored tests */ + do_j1979_basics(); /* Ask basic info from ECU */ + do_j1979_cms(); /* Get test results for monitored systems */ + do_j1979_ncms(0); /* And non-continuously monitored tests */ - OkToApp() ; + OkToApp(); } else { - fprintf(stderr, "Connection to ECU failed\n") ; - fprintf(stderr, "Please check :\n") ; - fprintf(stderr, "\tAdapter is connected to PC\n") ; - fprintf(stderr, "\tCable is connected to Vehicle\n") ; - fprintf(stderr, "\tVehicle is switched on\n") ; - fprintf(stderr, "\tVehicle is OBDII compliant\n") ; - - BadToApp() ; + fprintf(stderr, "Connection to ECU failed\n"); + fprintf(stderr, "Please check :\n"); + fprintf(stderr, "\tAdapter is connected to PC\n"); + fprintf(stderr, "\tCable is connected to Vehicle\n"); + fprintf(stderr, "\tVehicle is switched on\n"); + fprintf(stderr, "\tVehicle is OBDII compliant\n"); + + BadToApp(); } } +static void +aif_debug(void *data) { + debugging = ((char *)data)[0]; -static void aif_debug (void *data) { - debugging = ((char *) data)[0] ; - - OkToApp() ; + OkToApp(); - fprintf(stderr, "AIF: Debugging is %sabled\n", - debugging ? "En" : "Dis") ; + fprintf(stderr, "AIF: Debugging is %sabled\n", debugging ? "En" : "Dis"); } - -typedef void (*aif_func) (void *) ; +typedef void (*aif_func)(void *); struct AIFcommand { - const int code ; - const int length ; - const char *name ; - const aif_func func ; -} ; - + const int code; + const int length; + const char *name; + const aif_func func; +}; const struct AIFcommand aif_commands[] = { - { FREEDIAG_AIF_NO_OP , 0, "Do Nothing" , aif_noop }, - { FREEDIAG_AIF_EXIT , 0, "Exit ScanTool" , aif_exit }, - { FREEDIAG_AIF_MONITOR , 0, "Monitor" , aif_monitor }, - { FREEDIAG_AIF_WATCH , 0, "Watch diagnostic bus" , aif_watch }, - { FREEDIAG_AIF_CLEAR_DTC, 0, "Clear DTC's from ECU" , aif_clear_dtc }, - { FREEDIAG_AIF_ECUS , 0, "Show ECU information" , aif_ecus }, - { FREEDIAG_AIF_SET , 2, "Set various options" , aif_set }, - { FREEDIAG_AIF_TEST , 0, "Perform various tests" , aif_test }, - { FREEDIAG_AIF_SCAN , 0, "Scan for Connection" , aif_scan }, - { FREEDIAG_AIF_DIAG , 0, "Extended diagnostics" , aif_diag }, - { FREEDIAG_AIF_VW , 0, "VW diagnostic protocol", aif_vw }, - { FREEDIAG_AIF_DYNO , 0, "Dyno functions" , aif_dyno }, - { FREEDIAG_AIF_DEBUG , 1, "Set/Unset debug" , aif_debug }, - { FREEDIAG_AIF_DISCONNECT,0, "Disconnect from car" , aif_disconnect}, - { 0, 0, NULL, NULL } -} ; - - -static void do_aif_command (void) { - char data_buffer[FREEDIAG_AIF_INPUT_MAX] ; - int i, j ; - - const struct AIFcommand *command=NULL ; - int cmd = fgetc(stdin) ; + {FREEDIAG_AIF_NO_OP, 0, "Do Nothing", aif_noop}, + {FREEDIAG_AIF_EXIT, 0, "Exit ScanTool", aif_exit}, + {FREEDIAG_AIF_MONITOR, 0, "Monitor", aif_monitor}, + {FREEDIAG_AIF_WATCH, 0, "Watch diagnostic bus", aif_watch}, + {FREEDIAG_AIF_CLEAR_DTC, 0, "Clear DTC's from ECU", aif_clear_dtc}, + {FREEDIAG_AIF_ECUS, 0, "Show ECU information", aif_ecus}, + {FREEDIAG_AIF_SET, 2, "Set various options", aif_set}, + {FREEDIAG_AIF_TEST, 0, "Perform various tests", aif_test}, + {FREEDIAG_AIF_SCAN, 0, "Scan for Connection", aif_scan}, + {FREEDIAG_AIF_DIAG, 0, "Extended diagnostics", aif_diag}, + {FREEDIAG_AIF_VW, 0, "VW diagnostic protocol", aif_vw}, + {FREEDIAG_AIF_DYNO, 0, "Dyno functions", aif_dyno}, + {FREEDIAG_AIF_DEBUG, 1, "Set/Unset debug", aif_debug}, + {FREEDIAG_AIF_DISCONNECT, 0, "Disconnect from car", aif_disconnect}, + {0, 0, NULL, NULL}}; + +static void +do_aif_command(void) { + char data_buffer[FREEDIAG_AIF_INPUT_MAX]; + int i, j; + + const struct AIFcommand *command = NULL; + int cmd = fgetc(stdin); if (cmd == -1) { - fprintf (stderr, - "scantool: Unexpected EOF from Application Interface\n") ; - BadToApp() ; - exit (1) ; + fprintf(stderr, "scantool: Unexpected EOF from Application Interface\n"); + BadToApp(); + exit(1); } - for (i = 0 ; aif_commands[i] . name != NULL ; i++) { - command = & (aif_commands[i]) ; + for (i = 0; aif_commands[i].name != NULL; i++) { + command = &(aif_commands[i]); if (command->code == cmd) { if (debugging) { - fprintf(stderr, "CMD: %d %s\n", cmd, - command->name); + fprintf(stderr, "CMD: %d %s\n", cmd, command->name); } - break ; + break; } } if (command->name == NULL) { - fprintf(stderr, - "scantool: Application sent AIF an illegal command '%d'\n", - cmd) ; - BadToApp() ; - exit (1) ; + fprintf(stderr, "scantool: Application sent AIF an illegal command '%d'\n", + cmd); + BadToApp(); + exit(1); } - for (j = 0; - j < command->length && j < FREEDIAG_AIF_INPUT_MAX && !feof(stdin); + for (j = 0; j < command->length && j < FREEDIAG_AIF_INPUT_MAX && !feof(stdin); j++) { data_buffer[j] = getc(stdin); } - command->func(data_buffer) ; + command->func(data_buffer); - fflush(stdout) ; + fflush(stdout); } - -void enter_aif (const char *name) { - fprintf(stderr, "%s AIF: version %s\n", name, PACKAGE_VERSION) ; - set_init() ; +void +enter_aif(const char *name) { + fprintf(stderr, "%s AIF: version %s\n", name, PACKAGE_VERSION); + set_init(); while (1) { do_aif_command(); } } - - diff --git a/scantool/scantool_aif.h b/scantool/scantool_aif.h index 2923901a..aa71cfa7 100644 --- a/scantool/scantool_aif.h +++ b/scantool/scantool_aif.h @@ -28,6 +28,4 @@ * */ - -void enter_aif ( const char *name ) ; - +void enter_aif(const char *name); diff --git a/scantool/scantool_cli.c b/scantool/scantool_cli.c index 908a4391..22c896a3 100644 --- a/scantool/scantool_cli.c +++ b/scantool/scantool_cli.c @@ -45,24 +45,31 @@ #include "scantool_cli.h" #ifdef HAVE_LIBREADLINE -#include -#include +# include +# include #endif - -#define PROMPTBUFSIZE 80 //Length of prompt before the '>' character. +#define PROMPTBUFSIZE 80 // Length of prompt before the '>' character. #define CLI_MAXARGS 300 const char *progname; -const char projname[]=PROJECT_NAME; - -int diag_cli_debug; //debug level +const char projname[] = PROJECT_NAME; -FILE *global_logfp; /* Monitor log output file pointer */ -unsigned long global_log_tstart; /* timestamp datum (in ms) of beginning of log */ -#define LOG_FORMAT "FREEDIAG log format 0.2" +// debug level +DIAG_ATOMIC_STATICALLY_DECL_INIT(static diag_atomic_int diag_cli_debug) +void +diag_cli_debug_store(int d) { + diag_atomic_store_int(&diag_cli_debug, d); +} +int +diag_cli_debug_load(void) { + return diag_atomic_load_int(&diag_cli_debug); +} +FILE *global_logfp; /* Monitor log output file pointer */ +unsigned long global_log_tstart; /* timestamp datum (in ms) of beginning of log */ +#define LOG_FORMAT "FREEDIAG log format 0.2" -//ugly, global data. Could be struct-ed together eventually +// ugly, global data. Could be struct-ed together eventually struct diag_l2_conn *global_l2_conn; struct diag_l3_conn *global_l3_conn; enum globstate global_state = STATE_IDLE; @@ -83,60 +90,57 @@ static int cmd_date(int argc, char **argv); static int cmd_rem(int argc, char **argv); static int cmd_source(int argc, char **argv); -const struct cmd_tbl_entry *root_cmd_table; /* point to current root table */ +const struct cmd_tbl_entry *root_cmd_table; /* point to current root table */ /* this table is appended to the "extra" cmdtable to construct the whole root cmd table */ static const struct cmd_tbl_entry basic_cmd_table[] = { - { "log", "log ", "Log monitor data to ", - cmd_log, FLAG_FILE_ARG, NULL}, - { "stoplog", "stoplog", "Stop logging", cmd_stoplog, 0, NULL}, + {"log", "log ", "Log monitor data to ", cmd_log, FLAG_FILE_ARG, + NULL}, + {"stoplog", "stoplog", "Stop logging", cmd_stoplog, 0, NULL}, - { "play", "play filename", "Play back data from ", - cmd_play, FLAG_HIDDEN | FLAG_FILE_ARG, NULL}, + {"play", "play filename", "Play back data from ", cmd_play, + FLAG_HIDDEN | FLAG_FILE_ARG, NULL}, - { "set", "set ", - "Sets/displays parameters, \"set help\" for more info", NULL, - 0, set_cmd_table}, + {"set", "set ", + "Sets/displays parameters, \"set help\" for more info", NULL, 0, set_cmd_table}, - { "test", "test ", - "Perform various tests, \"test help\" for more info", NULL, - 0, test_cmd_table}, + {"test", "test ", + "Perform various tests, \"test help\" for more info", NULL, 0, test_cmd_table}, - { "diag", "diag ", - "Extended diagnostic functions, \"diag help\" for more info", NULL, - 0, diag_cmd_table}, + {"diag", "diag ", + "Extended diagnostic functions, \"diag help\" for more info", NULL, 0, + diag_cmd_table}, - { "vw", "vw ", - "'96-'98 Volvo 850/S70/V70/etc functions, \"850 help\" for more info", NULL, - 0, v850_cmd_table}, + {"850", "850 ", + "'96-'98 Volvo 850/S70/V70/etc functions, \"850 help\" for more info", NULL, 0, + v850_cmd_table}, - { "dyno", "dyno ", "Read commands from a file", cmd_source, FLAG_FILE_ARG, NULL}, + {"date", "date", "Prints date & time", cmd_date, FLAG_HIDDEN, NULL}, + {"#", "#", "Does nothing", cmd_rem, FLAG_HIDDEN, NULL}, + {"source", "source ", "Read commands from a file", cmd_source, FLAG_FILE_ARG, + NULL}, - { "help", "help [command]", "Gives help for a command", cmd_help, 0, NULL }, - { "?", "? [command]", "Gives help for a command", cmd_help, FLAG_HIDDEN, NULL }, - { "exit", "exit", "Exits program", cmd_exit, 0, NULL}, - { "quit", "quit", "Exits program", cmd_exit, FLAG_HIDDEN, NULL}, - { NULL, NULL, NULL, NULL, 0, NULL} -}; + {"help", "help [command]", "Gives help for a command", cmd_help, 0, NULL}, + {"?", "? [command]", "Gives help for a command", cmd_help, FLAG_HIDDEN, NULL}, + {"exit", "exit", "Exits program", cmd_exit, 0, NULL}, + {"quit", "quit", "Exits program", cmd_exit, FLAG_HIDDEN, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL}}; #ifdef HAVE_LIBREADLINE -//current global command level for command completion +// current global command level for command completion static const struct cmd_tbl_entry *current_cmd_level; -//command level in the command line, also needed for command completion +// command level in the command line, also needed for command completion static const struct cmd_tbl_entry *completion_cmd_level; #endif @@ -195,21 +199,21 @@ command_generator(const char *text, int state) { static int list_index, length; const struct cmd_tbl_entry *cmd_entry; - //a new word to complete + // a new word to complete if (state == 0) { list_index = 0; length = strlen(text); } - //find the command + // find the command while (completion_cmd_level[list_index].command != NULL) { cmd_entry = &completion_cmd_level[list_index]; list_index++; - if (strncmp(cmd_entry->command, text, length) == 0 && !(cmd_entry->flags & FLAG_HIDDEN)) { + if (strncmp(cmd_entry->command, text, length) == 0 && + !(cmd_entry->flags & FLAG_HIDDEN)) { char *ret_name; - //we must return a copy of the string; libreadline frees it for us - if (diag_malloc(&ret_name, - strlen(cmd_entry->command) + 1) != 0) { + // we must return a copy of the string; libreadline frees it for us + if (diag_malloc(&ret_name, strlen(cmd_entry->command) + 1) != 0) { return (char *)NULL; } strcpy(ret_name, cmd_entry->command); @@ -223,75 +227,85 @@ char ** scantool_completion(const char *text, int start, UNUSED(int end)) { char **matches; - //start == 0 is when the command line is either empty or contains only whitespaces + // start == 0 is when the command line is either empty or contains only whitespaces if (start == 0) { - //we are at the beginning of the command line, so the completion command level is equal to the current command level + // we are at the beginning of the command line, so the completion command + // level is equal to the current command level completion_cmd_level = current_cmd_level; rl_attempted_completion_over = 0; } //(start != end) means that we are trying to complete a command; - //(start > 0 and start == end) means that all commands are completed and we need to check for their sub-commands; - //we handle here both cases so that the completion_cmd_level is always up-to-date + //(start > 0 and start == end) means that all commands are completed and we need to + // check for their sub-commands; we handle here both cases so that the + // completion_cmd_level is always up-to-date else { - //parse the command line so that we know on what command level we should do the completion + // parse the command line so that we know on what command level we should + // do the completion struct cmd_tbl_entry const *parsed_level = current_cmd_level; - //we need to omit leading whitespaces + // we need to omit leading whitespaces size_t begin_at = strspn(rl_line_buffer, " "); const char *cmd = &rl_line_buffer[begin_at]; - //now get the length of the first command + // now get the length of the first command size_t cmd_length = strcspn(cmd, " "); - //check all completed commands + // check all completed commands while (cmd_length > 0 && cmd[cmd_length] == ' ') { - //find out what it might be... + // find out what it might be... bool found = 0; for (int i = 0; parsed_level[i].command != NULL; i++) { - //if found the command on the current level + // if found the command on the current level if (!(parsed_level[i].flags & FLAG_HIDDEN) && - strlen(parsed_level[i].command) == cmd_length && - strncmp(parsed_level[i].command, cmd, cmd_length) == 0) { - //does it have sub-commands? + strlen(parsed_level[i].command) == cmd_length && + strncmp(parsed_level[i].command, cmd, cmd_length) == + 0) { + // does it have sub-commands? if (parsed_level[i].sub_cmd_tbl != NULL) { - //go deeper + // go deeper parsed_level = parsed_level[i].sub_cmd_tbl; rl_attempted_completion_over = 0; found = 1; } else if (parsed_level[i].flags & FLAG_FILE_ARG) { - //the command accepts a filename as an argument, so use the libreadline's filename completion + // the command accepts a filename as an + // argument, so use the libreadline's + // filename completion rl_attempted_completion_over = 0; return NULL; } else { - //if no sub-commands, then no more completion + // if no sub-commands, then no more + // completion rl_attempted_completion_over = 1; return NULL; } - //stop searching on this level and go to another command in the command line (if any) + // stop searching on this level and go to another + // command in the command line (if any) break; } } - //went through all commands and didn't find anything? then it is an unknown command + // went through all commands and didn't find anything? then it is + // an unknown command if (!found) { rl_attempted_completion_over = 1; return NULL; } - //move past the just-parsed command + // move past the just-parsed command cmd = &cmd[cmd_length]; - //again, omit whitespaces + // again, omit whitespaces begin_at = strspn(cmd, " "); cmd = &cmd[begin_at]; - //length of the next command + // length of the next command cmd_length = strcspn(cmd, " "); } - //update the completion command level for the command_generator() function + // update the completion command level for the command_generator() function completion_cmd_level = parsed_level; } matches = rl_completion_matches(text, command_generator); if (matches == NULL) { - //this will disable the default (filename and username) completion in case no command matches are found + // this will disable the default (filename and username) completion in case + // no command matches are found rl_attempted_completion_over = 1; } return matches; @@ -299,24 +313,25 @@ scantool_completion(const char *text, int start, UNUSED(int end)) { static void readline_init(const struct cmd_tbl_entry *curtable) { - //preset levels for current table + // preset levels for current table current_cmd_level = curtable; completion_cmd_level = curtable; - //our custom completion function + // our custom completion function rl_attempted_completion_function = scantool_completion; } -#else // so no libreadline +#else // so no libreadline static char * get_input(const char *prompt) { return basic_get_input(prompt, stdin); } -static void readline_init(UNUSED(const struct cmd_tbl_entry *cmd_table)) {} +static void +readline_init(UNUSED(const struct cmd_tbl_entry *cmd_table)) {} -#endif //HAVE_LIBREADLINE +#endif // HAVE_LIBREADLINE static char * command_line_input(const char *prompt, FILE *instream) { @@ -330,7 +345,7 @@ command_line_input(const char *prompt, FILE *instream) { int help_common(int argc, char **argv, const struct cmd_tbl_entry *cmd_table) { -/* int i;*/ + /* int i;*/ const struct cmd_tbl_entry *ctp; if (argc > 1) { @@ -362,7 +377,7 @@ help_common(int argc, char **argv, const struct cmd_tbl_entry *cmd_table) { if (ctp->flags & FLAG_CUSTOM) { /* list custom subcommands too */ printf("Custom commands for the current level:\n"); - char cust_special[]="?"; + char cust_special[] = "?"; char *pcs = cust_special; char **temp_argv = &pcs; ctp->routine(1, temp_argv); @@ -371,7 +386,6 @@ help_common(int argc, char **argv, const struct cmd_tbl_entry *cmd_table) { } printf("\nTry \"help \" for further help\n"); - return CMD_OK; } @@ -380,7 +394,6 @@ cmd_help(int argc, char **argv) { return help_common(argc, argv, root_cmd_table); } - static int cmd_date(UNUSED(int argc), UNUSED(char **argv)) { struct tm *tm; @@ -393,13 +406,11 @@ cmd_date(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - static int cmd_rem(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - void log_timestamp(const char *prefix) { unsigned long tv; @@ -426,12 +437,12 @@ log_command(int argc, char **argv) { static int cmd_log(int argc, char **argv) { - char autofilename[20]=""; + char autofilename[20] = ""; char *file; time_t now; int i; - file=autofilename; + file = autofilename; if (global_logfp != NULL) { printf("Already logging\n"); return CMD_FAILED; @@ -439,26 +450,28 @@ cmd_log(int argc, char **argv) { /* Turn on logging */ if (argc > 1) { - file = argv[1]; //if a file name was specified, use that + file = argv[1]; // if a file name was specified, use that } else { - //else, generate an auto log file + // else, generate an auto log file for (i = 0; i < 100; i++) { FILE *testexist; - sprintf(autofilename,"log.%02d",i); + sprintf(autofilename, "log.%02d", i); testexist = fopen(autofilename, "r"); if (testexist == NULL) { - //file name is free: use that + // file name is free: use that break; } fclose(testexist); } if (i == 100) { - printf("Can't create log.%d; remember to clean old auto log files\n",i); + printf("Can't create log.%d; remember to clean old auto log " + "files\n", + i); return CMD_FAILED; } } - global_logfp = fopen(file, "a"); //add to end of log or create file + global_logfp = fopen(file, "a"); // add to end of log or create file if (global_logfp == NULL) { printf("Failed to create log file %s\n", file); @@ -466,19 +479,17 @@ cmd_log(int argc, char **argv) { } now = time(NULL); - //reset timestamp reference: - global_log_tstart=diag_os_getms(); + // reset timestamp reference: + global_log_tstart = diag_os_getms(); fprintf(global_logfp, "%s\n", LOG_FORMAT); log_timestamp("#"); - fprintf(global_logfp, "logging started at %s", - asctime(localtime(&now))); + fprintf(global_logfp, "logging started at %s", asctime(localtime(&now))); printf("Logging to file %s\n", file); return CMD_OK; } - static int cmd_stoplog(UNUSED(int argc), UNUSED(char **argv)) { /* Turn off logging */ @@ -496,7 +507,7 @@ cmd_stoplog(UNUSED(int argc), UNUSED(char **argv)) { static int cmd_play(int argc, char **argv) { FILE *fp; - //int linenr; + // int linenr; /* Turn on logging for monitor mode */ if (argc < 2) { @@ -510,7 +521,7 @@ cmd_play(int argc, char **argv) { return CMD_FAILED; } - //linenr = 0; //not used yet ? + // linenr = 0; //not used yet ? /* Read data file in */ /* XXX logging */ @@ -522,29 +533,28 @@ cmd_play(int argc, char **argv) { printf("DATE:\t+/- 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; + case '-': + case '+': + case 'E': + case 'e': + case 'S': + case 's': + case 'Q': + case 'q': + break; } - } fclose(fp); return CMD_OK; } - /* Find matching cmd_tbl_entry for command *cmd in table *cmdt. * Returns the command or the custom handler if * no match was found and the custom handler exists. */ -static const struct cmd_tbl_entry *find_cmd(const struct cmd_tbl_entry *cmdt, const char *cmd) { +static const struct cmd_tbl_entry * +find_cmd(const struct cmd_tbl_entry *cmdt, const char *cmd) { const struct cmd_tbl_entry *ctp; const struct cmd_tbl_entry *custom_cmd; @@ -573,21 +583,23 @@ static const struct cmd_tbl_entry *find_cmd(const struct cmd_tbl_entry *cmdt, co * If argc is supplied, then this is one shot cli, ie run the command */ static int -do_cli(const struct cmd_tbl_entry *cmd_tbl, const char *prompt, FILE *instream, int argc, char **argv) { +do_cli(const struct cmd_tbl_entry *cmd_tbl, const char *prompt, FILE *instream, int argc, + char **argv) { /* Build up argc/argv */ const struct cmd_tbl_entry *ctp; int cmd_argc; char *cmd_argv[CLI_MAXARGS]; char *input = NULL; int rv; - bool done; //when set, sub-command processing is ended and returns to upper level + bool done; // when set, sub-command processing is ended and returns to upper level int i; - char promptbuf[PROMPTBUFSIZE]; /* Was 1024, who needs that long a prompt? (the part before user input up to '>') */ - static char nullstr[2] = {0,0}; + char promptbuf[PROMPTBUFSIZE]; /* Was 1024, who needs that long a prompt? (the part + before user input up to '>') */ + static char nullstr[2] = {0, 0}; #ifdef HAVE_LIBREADLINE - //set the current command level for command completion + // set the current command level for command completion current_cmd_level = cmd_tbl; #endif @@ -611,19 +623,20 @@ do_cli(const struct cmd_tbl_entry *cmd_tbl, const char *prompt, FILE *instream, /* Parse it */ inptr = input; - if (*inptr == '@') { //printing comment + if (*inptr == '@') { // printing comment printf("%s\n", inptr); continue; } - if (*inptr == '#') { //non-printing comment + if (*inptr == '#') { // non-printing comment continue; } cmd_argc = 0; - while ( (s = strtok(inptr, " \t")) != NULL ) { + while ((s = strtok(inptr, " \t")) != NULL) { cmd_argv[cmd_argc] = s; inptr = NULL; - if (cmd_argc == (ARRAY_SIZE(cmd_argv)-1)) { - fprintf(stderr, "Warning : excessive # of arguments\n"); + if (cmd_argc == (ARRAY_SIZE(cmd_argv) - 1)) { + fprintf(stderr, + "Warning : excessive # of arguments\n"); break; } cmd_argc++; @@ -645,27 +658,24 @@ do_cli(const struct cmd_tbl_entry *cmd_tbl, const char *prompt, FILE *instream, if (ctp == NULL) { printf("Unrecognized command. Try \"help\"\n"); if (argc) { - //was a single command : exit this level of do_cli() + // was a single command : exit this level of do_cli() done = 1; break; } - //else : continue getting input + // else : continue getting input continue; } if (ctp->sub_cmd_tbl) { /* has sub-commands */ log_command(1, cmd_argv); - snprintf(promptbuf, PROMPTBUFSIZE,"%s/%s", - prompt, ctp->command); + snprintf(promptbuf, PROMPTBUFSIZE, "%s/%s", prompt, ctp->command); /* Sub menu */ - rv = do_cli(ctp->sub_cmd_tbl, - promptbuf, - instream, - cmd_argc-1, - &cmd_argv[1]); + rv = do_cli(ctp->sub_cmd_tbl, promptbuf, instream, cmd_argc - 1, + &cmd_argv[1]); #ifdef HAVE_LIBREADLINE - //went out of the sub-menu, so update the command level for command completion + // went out of the sub-menu, so update the command level for + // command completion current_cmd_level = cmd_tbl; #endif if (rv == CMD_EXIT) { // allow exiting prog. from a @@ -678,13 +688,13 @@ do_cli(const struct cmd_tbl_entry *cmd_tbl, const char *prompt, FILE *instream, log_command(cmd_argc, cmd_argv); rv = ctp->routine(cmd_argc, cmd_argv); switch (rv) { - case CMD_USAGE: - printf("Usage: %s\n%s\n", ctp->usage, ctp->help); - break; - case CMD_EXIT: - case CMD_UP: - done = 1; - break; + case CMD_USAGE: + printf("Usage: %s\n%s\n", ctp->usage, ctp->help); + break; + case CMD_EXIT: + case CMD_UP: + done = 1; + break; } } @@ -693,7 +703,7 @@ do_cli(const struct cmd_tbl_entry *cmd_tbl, const char *prompt, FILE *instream, done = 1; break; } - } //while !done + } // while !done if (input) { free(input); @@ -702,14 +712,17 @@ do_cli(const struct cmd_tbl_entry *cmd_tbl, const char *prompt, FILE *instream, return CMD_OK; } if (rv == CMD_EXIT) { - char *disco="disconnect"; + char *disco = "disconnect"; if (global_logfp != NULL) { cmd_stoplog(0, NULL); } - do_cli(diag_cmd_table, "", instream, 1, &disco); //XXX should be called recursively in case there are >1 active L3 conns... + do_cli(diag_cmd_table, "", instream, 1, &disco); // XXX should be called + // recursively in case + // there are >1 active L3 + // conns... - rv=diag_end(); + rv = diag_end(); if (rv) { fprintf(stderr, FLFMT "diag_end failed !?\n", FL); } @@ -727,10 +740,10 @@ command_file(const char *filename) { int rv; FILE *fstream; - if ( (fstream=fopen(filename, "r"))) { - rv=do_cli(root_cmd_table, progname, fstream, 0, NULL); + if ((fstream = fopen(filename, "r"))) { + rv = do_cli(root_cmd_table, progname, fstream, 0, NULL); fclose(fstream); - return (rv==CMD_EXIT)? CMD_EXIT:CMD_OK; + return (rv == CMD_EXIT) ? CMD_EXIT : CMD_OK; } return CMD_FAILED; } @@ -741,25 +754,25 @@ cmd_source(int argc, char **argv) { int rv; if (argc < 2) { - printf("No filename\n"); + printf("No filename\n"); return CMD_USAGE; } file = argv[1]; - rv=command_file(file); + rv = command_file(file); if (rv == CMD_FAILED) { - printf("Couldn't read %s\n", file); + printf("Couldn't read %s\n", file); } return rv; } -//rc_file : returns CMD_OK or CMD_EXIT only. +// rc_file : returns CMD_OK or CMD_EXIT only. static int rc_file(void) { int rv; - //this loads either a $home/..rc or ./.ini (in order of preference) - //to load general settings. + // this loads either a $home/..rc or ./.ini (in order of + // preference) to load general settings. /* * "." files don't play that well on some systems. @@ -782,34 +795,36 @@ rc_file(void) { strcat(rchomeinit, projname); strcat(rchomeinit, "rc"); - rv=command_file(rchomeinit); + rv = command_file(rchomeinit); if (rv == CMD_FAILED) { - fprintf(stderr, FLFMT "Could not load rc file %s; ", FL, rchomeinit); - newrcfile=fopen(rchomeinit,"a"); + fprintf(stderr, FLFMT "Could not load rc file %s; ", FL, + rchomeinit); + newrcfile = fopen(rchomeinit, "a"); if (newrcfile) { - //create the file if it didn't exist - fprintf(newrcfile, "\n#empty rcfile auto created by %s\n",progname); + // create the file if it didn't exist + fprintf(newrcfile, "\n#empty rcfile auto created by %s\n", + progname); fclose(newrcfile); fprintf(stderr, "empty file created.\n"); free(rchomeinit); return CMD_OK; } else { - //could not create empty rcfile - fprintf(stderr, "could not create empty file %s.", rchomeinit); + // could not create empty rcfile + fprintf(stderr, "could not create empty file %s.", + rchomeinit); free(rchomeinit); return CMD_OK; } } else { - //command_file was at least partly successful (rc file exists) - printf("%s: Settings loaded from %s\n",progname,rchomeinit); + // command_file was at least partly successful (rc file exists) + printf("%s: Settings loaded from %s\n", progname, rchomeinit); free(rchomeinit); return CMD_OK; } - } //if (homedir) + } // if (homedir) #endif - #ifdef USE_INIFILE char *inihomeinit; rv = diag_malloc(&inihomeinit, strlen(progname) + strlen(".ini") + 1); @@ -821,29 +836,31 @@ rc_file(void) { strcpy(inihomeinit, progname); strcat(inihomeinit, ".ini"); - rv=command_file(inihomeinit); + rv = command_file(inihomeinit); if (rv == CMD_FAILED) { - fprintf(stderr, FLFMT "Problem with %s, no configuration loaded\n", FL, inihomeinit); + fprintf(stderr, FLFMT "Problem with %s, no configuration loaded\n", FL, + inihomeinit); free(inihomeinit); return CMD_OK; } printf("%s: Settings loaded from %s\n", progname, inihomeinit); free(inihomeinit); #endif - return rv; //could be CMD_EXIT - + return rv; // could be CMD_EXIT } /* start a cli with as a prompt, and optionally run the file */ void -enter_cli(const char *name, const char *initscript, const struct cmd_tbl_entry *extra_cmdtable) { - int rc_rv=CMD_OK; +enter_cli(const char *name, const char *initscript, + const struct cmd_tbl_entry *extra_cmdtable) { + int rc_rv = CMD_OK; global_logfp = NULL; progname = name; // alloc a new table combining extra table (if applicable) and basic table int i = 0; const struct cmd_tbl_entry *ctp_iter; struct cmd_tbl_entry *ctp; + DIAG_ATOMIC_INITSTATIC(&diag_cli_debug); for (ctp_iter = extra_cmdtable; ctp_iter && ctp_iter->command; ctp_iter++) { i++; } @@ -855,30 +872,33 @@ enter_cli(const char *name, const char *initscript, const struct cmd_tbl_entry * memcpy(&ctp[i], basic_cmd_table, sizeof(basic_cmd_table)); root_cmd_table = ctp; - readline_init(ctp); set_init(); if (initscript != NULL) { - int rv=command_file(initscript); + int rv = command_file(initscript); switch (rv) { - case CMD_OK: - /* script was succesful, start a normal CLI afterwards */ - break; - case CMD_FAILED: - printf("Problem with file %s\n", initscript); - // fallthrough, yes - default: - case CMD_EXIT: - goto exit_cleanup; + case CMD_OK: + /* script was succesful, start a normal CLI afterwards */ + break; + case CMD_FAILED: + printf("Problem with file %s\n", initscript); + // fallthrough, yes + default: + case CMD_EXIT: + goto exit_cleanup; } } else { /* print banner and load rc file, only if running without an initscript */ printf("%s: Type HELP for a list of commands\n", name); printf("%s: Type SCAN to start ODBII Scan\n", name); printf("%s: Then use MONITOR to monitor real-time data\n", name); - printf("%s: **** IMPORTANT : this is beta software ! Use at your own risk.\n", name); - printf("%s: **** Remember, \"debug all -1\" displays all debugging info.\n", name); + printf("%s: **** IMPORTANT : this is beta software ! Use at your own " + "risk.\n", + name); + printf("%s: **** Remember, \"debug all -1\" displays all debugging " + "info.\n", + name); rc_rv = rc_file(); } @@ -891,8 +911,8 @@ enter_cli(const char *name, const char *initscript, const struct cmd_tbl_entry * free(ctp); root_cmd_table = NULL; set_close(); + DIAG_ATOMIC_DEL(&diag_cli_debug); return; - } /* @@ -910,15 +930,16 @@ enter_cli(const char *name, const char *initscript, const struct cmd_tbl_entry * * [-][0-9] : dec * Returns 0 if unable to decode. */ -int htoi(char *buf) { +int +htoi(char *buf) { /* Hex text to int */ int rv = 0; int base = 10; - int sign=0; //1 = positive; 0 =neg + int sign = 0; // 1 = positive; 0 =neg if (*buf != '-') { - //change sign - sign=1; + // change sign + sign = 1; } else { buf++; } @@ -955,13 +976,14 @@ int htoi(char *buf) { buf++; } - return sign? rv:-rv ; + return sign ? rv : -rv; } /* * Wait until ENTER is pressed */ -void wait_enter(const char *message) { +void +wait_enter(const char *message) { printf("%s", message); while (1) { int ch = getc(stdin); @@ -974,17 +996,16 @@ void wait_enter(const char *message) { /* * Determine whether ENTER has been pressed */ -int pressed_enter() { +int +pressed_enter() { return diag_os_ipending(); } - int cmd_up(UNUSED(int argc), UNUSED(char **argv)) { return CMD_UP; } - int cmd_exit(UNUSED(int argc), UNUSED(char **argv)) { return CMD_EXIT; diff --git a/scantool/scantool_cli.h b/scantool/scantool_cli.h index ada1e693..6a6df277 100644 --- a/scantool/scantool_cli.h +++ b/scantool/scantool_cli.h @@ -34,26 +34,27 @@ extern "C" { #endif struct cmd_tbl_entry { - const char *command; /* Command name */ - const char *usage; /* Usage info */ - const char *help; /* Help Text */ - int (*routine)(int argc, char **argv); /* Command Routine */ - const int flags; /* Flag */ - - const struct cmd_tbl_entry *sub_cmd_tbl; /* Next layer */ + const char *command; /* Command name */ + const char *usage; /* Usage info */ + const char *help; /* Help Text */ + int (*routine)(int argc, char **argv); /* Command Routine */ + const int flags; /* Flag */ + const struct cmd_tbl_entry *sub_cmd_tbl; /* Next layer */ }; /* Return values from the commands */ -#define CMD_OK 0 /* OK */ -#define CMD_USAGE 1 /* Bad usage, print usage info */ -#define CMD_FAILED 2 /* Cmd failed */ -#define CMD_EXIT 3 /* Exit called */ -#define CMD_UP 4 /* Go up one level in command tree */ +#define CMD_OK 0 /* OK */ +#define CMD_USAGE 1 /* Bad usage, print usage info */ +#define CMD_FAILED 2 /* Cmd failed */ +#define CMD_EXIT 3 /* Exit called */ +#define CMD_UP 4 /* Go up one level in command tree */ -#define FLAG_HIDDEN (1 << 0) /* Hidden command */ +#define FLAG_HIDDEN (1 << 0) /* Hidden command */ #define FLAG_FILE_ARG (1 << 1) /* Command accepts a filename as an argument*/ -#define FLAG_CUSTOM (1 << 2) /* Command handles other subcommands not in the subtable, max 1 per table */ +#define FLAG_CUSTOM \ + (1 << 2) /* Command handles other subcommands not in the subtable, max 1 per \ + table */ /*** Public CLI functions */ @@ -61,9 +62,8 @@ int help_common(int argc, char **argv, const struct cmd_tbl_entry *cmd_table); void wait_enter(const char *message); int pressed_enter(void); -void enter_cli(const char *name, const char *initscript, const struct cmd_tbl_entry *extra_cmdtable); - - +void enter_cli(const char *name, const char *initscript, + const struct cmd_tbl_entry *extra_cmdtable); /** Prompt for some input. * Returns a new 0-terminated string with trailing CR/LF stripped @@ -72,9 +72,7 @@ void enter_cli(const char *name, const char *initscript, const struct cmd_tbl_en * have readline, and when reading init or command files. * No line editing or history. */ -char * -basic_get_input(const char *prompt, FILE *instream); - +char *basic_get_input(const char *prompt, FILE *instream); /** * Decimal/Octal/Hex to integer routine @@ -87,55 +85,50 @@ basic_get_input(const char *prompt, FILE *instream); */ int htoi(char *buf); - int cmd_up(int argc, char **argv); int cmd_exit(int argc, char **argv); +/* debug level */ +void diag_cli_debug_store(int d); +int diag_cli_debug_load(void); - - -extern int diag_cli_debug; /* debug level */ -extern FILE *global_logfp; /* Monitor log output file pointer */ +extern FILE *global_logfp; /* Monitor log output file pointer */ void log_timestamp(const char *prefix); - - /** Global parameters set by user interface **/ /* struct global_cfg contains all global parameters */ extern struct globcfg { - bool units; /* English(1) or Metric(0) display */ + bool units; /* English(1) or Metric(0) display */ - uint8_t tgt; /* u8; target address */ - uint8_t src; /* u8: source addr / tester ID */ - bool addrtype; /* Address type, 1 = functional */ - unsigned int speed; /* ECU comms speed */ + uint8_t tgt; /* u8; target address */ + uint8_t src; /* u8: source addr / tester ID */ + bool addrtype; /* Address type, 1 = functional */ + unsigned int speed; /* ECU comms speed */ - int initmode; /* Type of bus init (ISO9141/14230 only) */ - int L1proto; /* L1 (H/W) Protocol type */ - int L2proto; /* L2 (S/W) Protocol type; value of ->diag_l2_protocol. */ - int L2idx; /* index of that L2 proto in struct l2proto_list[] */ + int initmode; /* Type of bus init (ISO9141/14230 only) */ + int L1proto; /* L1 (H/W) Protocol type */ + int L2proto; /* L2 (S/W) Protocol type; value of ->diag_l2_protocol. */ + int L2idx; /* index of that L2 proto in struct l2proto_list[] */ - const char *l0name; /* L0 interface name to use */ - //struct diag_l0_device *dl0d; /* L0 device to use */ + const char *l0name; /* L0 interface name to use */ + // struct diag_l0_device *dl0d; /* L0 device to use */ } global_cfg; - enum globstate { - //specify numbers because some code checks (for global_state >= X) etc. - STATE_IDLE=0, /* Idle */ - STATE_WATCH=1, /* Watch mode */ - STATE_CONNECTED=2, /* Connected to ECU */ - STATE_L3ADDED=3, /* Layer 3 protocol added on Layer 2 */ - STATE_SCANDONE=4, /* J1978/9 Scan Done, so got J1979 PID list */ -}; //only for global_state ! + // specify numbers because some code checks (for global_state >= X) etc. + STATE_IDLE = 0, /* Idle */ + STATE_WATCH = 1, /* Watch mode */ + STATE_CONNECTED = 2, /* Connected to ECU */ + STATE_L3ADDED = 3, /* Layer 3 protocol added on Layer 2 */ + STATE_SCANDONE = 4, /* J1978/9 Scan Done, so got J1979 PID list */ +}; // only for global_state ! extern enum globstate global_state; extern struct diag_l0_device *global_dl0d; extern const char *progname; - /* Sub menus */ extern const struct cmd_tbl_entry set_cmd_table[]; @@ -151,5 +144,5 @@ extern const struct cmd_tbl_entry dyno_cmd_table[]; #if defined(__cplusplus) } -#endif +# endif #endif /* _SCANTOOL_CLI_H_ */ diff --git a/scantool/scantool_debug.c b/scantool/scantool_debug.c index c39d1575..d4582f5f 100644 --- a/scantool/scantool_debug.c +++ b/scantool/scantool_debug.c @@ -35,21 +35,19 @@ #include "scantool.h" #include "scantool_cli.h" - -//declare an array of structs to associate debug flag masks with short description. -//See diag.h +// declare an array of structs to associate debug flag masks with short description. +// See diag.h const struct debugflags_descr debugflags[] = { - {OPEN, "Open events","OPEN"}, - {CLOSE, "Close events","CLOSE"}, - {READ, "Read events","READ"}, - {WRITE, "Write events","WRITE"}, - {IOCTL, "Ioctl stuff (setspeed etc)","IOCTL"}, - {PROTO, "Protocol stuff","PROTO"}, - {INIT, "Init stuff","INIT"}, - {DATA, "Dump data if READ or WRITE","DATA"}, - {TIMER, "Timer stuff","TIMER"}, - {NIL, NULL, NULL} -}; + {OPEN, "Open events", "OPEN"}, + {CLOSE, "Close events", "CLOSE"}, + {READ, "Read events", "READ"}, + {WRITE, "Write events", "WRITE"}, + {IOCTL, "Ioctl stuff (setspeed etc)", "IOCTL"}, + {PROTO, "Protocol stuff", "PROTO"}, + {INIT, "Init stuff", "INIT"}, + {DATA, "Dump data if READ or WRITE", "DATA"}, + {TIMER, "Timer stuff", "TIMER"}, + {NIL, NULL, NULL}}; static int cmd_debug_help(int argc, char **argv); static int cmd_debug_show(int argc, char **argv); @@ -63,69 +61,68 @@ static int cmd_debug_all(int argc, char **argv); static int cmd_debug_l0test(int argc, char **argv); const struct cmd_tbl_entry debug_cmd_table[] = { - { "help", "help [command]", "Gives help for a command", - cmd_debug_help, 0, NULL}, - { "?", "? [command]", "Gives help for a command", - cmd_debug_help, FLAG_HIDDEN, NULL}, - - { "show", "show", "Shows current debug levels", - cmd_debug_show, 0, NULL}, - - { "l0", "l0 [val]", "Show/set Layer0 debug level", - cmd_debug_l0, 0, NULL}, - { "l1", "l1 [val]", "Show/set Layer1 debug level", - cmd_debug_l1, 0, NULL}, - { "l2", "l2 [val]", "Show/set Layer2 debug level", - cmd_debug_l2, 0, NULL}, - { "l3", "l3 [val]", "Show/set Layer3 debug level", - cmd_debug_l3, 0, NULL}, - { "cli", "cli [val]", "Show/set CLI debug level", - cmd_debug_cli, 0, NULL}, - { "all", "all [val]", "Show/set All layer debug level", - cmd_debug_all, 0, NULL}, - { "l0test", "l0test [testnum]", "Dumb interface tests. Disconnect from vehicle first !", - cmd_debug_l0test, 0, NULL}, - { "up", "up", "Return to previous menu level", - cmd_up, 0, NULL}, - { "quit","quit", "Exit program", - cmd_exit, FLAG_HIDDEN, NULL}, - { "exit", "exit", "Exit program", - cmd_exit, 0, NULL}, - - { NULL, NULL, NULL, NULL, 0, NULL} -}; + {"help", "help [command]", "Gives help for a command", cmd_debug_help, 0, NULL}, + {"?", "? [command]", "Gives help for a command", cmd_debug_help, FLAG_HIDDEN, + NULL}, + + {"show", "show", "Shows current debug levels", cmd_debug_show, 0, NULL}, + + {"l0", "l0 [val]", "Show/set Layer0 debug level", cmd_debug_l0, 0, NULL}, + {"l1", "l1 [val]", "Show/set Layer1 debug level", cmd_debug_l1, 0, NULL}, + {"l2", "l2 [val]", "Show/set Layer2 debug level", cmd_debug_l2, 0, NULL}, + {"l3", "l3 [val]", "Show/set Layer3 debug level", cmd_debug_l3, 0, NULL}, + {"cli", "cli [val]", "Show/set CLI debug level", cmd_debug_cli, 0, NULL}, + {"all", "all [val]", "Show/set All layer debug level", cmd_debug_all, 0, NULL}, + {"l0test", "l0test [testnum]", + "Dumb interface tests. Disconnect from vehicle first !", cmd_debug_l0test, 0, + NULL}, + {"up", "up", "Return to previous menu level", cmd_up, 0, NULL}, + {"quit", "quit", "Exit program", cmd_exit, FLAG_HIDDEN, NULL}, + {"exit", "exit", "Exit program", cmd_exit, 0, NULL}, + + {NULL, NULL, NULL, NULL, 0, NULL}}; static int cmd_debug_help(int argc, char **argv) { - if (argc<2) { - printf("Debugging flags are set per level according to the values set in diag.h\n"); - printf("Setting [val] to -1 will enable all debug messages for that level.\n" - "Available flags:\n"); + if (argc < 2) { + printf("Debugging flags are set per level according to the values set in " + "diag.h\n"); + printf("Setting [val] to -1 will enable all debug messages for that " + "level.\n" + "Available flags:\n"); int i; - for (i=0; debugflags[i].mask != NIL; i++) { + for (i = 0; debugflags[i].mask != NIL; i++) { printf("\t0x%4X: %s\n", debugflags[i].mask, debugflags[i].descr); } } return help_common(argc, argv, debug_cmd_table); } - +typedef struct { + void (*store)(int); + int (*load)(void); +} int_wrapper_object; +static int_wrapper_object diag_l0_debug = {diag_l0_debug_store, diag_l0_debug_load}; +static int_wrapper_object diag_l1_debug = {diag_l1_debug_store, diag_l1_debug_load}; +static int_wrapper_object diag_l2_debug = {diag_l2_debug_store, diag_l2_debug_load}; +static int_wrapper_object diag_l3_debug = {diag_l3_debug_store, diag_l3_debug_load}; +static int_wrapper_object diag_cli_debug = {diag_cli_debug_store, diag_cli_debug_load}; static int -cmd_debug_common( const char *txt, int *val, int argc, char **argv) { +cmd_debug_common(const char *txt, int_wrapper_object *val, int argc, char **argv) { int r; int i; - if ((argc ==2) && (argv[1][0]!='?')) { - //decode number unless it was ? + if ((argc == 2) && (argv[1][0] != '?')) { + // decode number unless it was ? r = htoi(argv[1]); - *val = r; + val->store(r); } - printf("%s debug is 0x%X: ", txt, *val); - for (i=0; debugflags[i].mask != NIL; i++) { - //check each flag and show what was enabled. - if (*val & debugflags[i].mask) { + printf("%s debug is 0x%X: ", txt, val->load()); + for (i = 0; debugflags[i].mask != NIL; i++) { + // check each flag and show what was enabled. + if (val->load() & debugflags[i].mask) { printf("%s ", debugflags[i].shortdescr); } } @@ -153,7 +150,7 @@ cmd_debug_l3(int argc, char **argv) { static int cmd_debug_cli(int argc, char **argv) { return cmd_debug_common("CLI", &diag_cli_debug, argc, argv); - //for now, value > 0x80 will enable all debugging info. + // for now, value > 0x80 will enable all debugging info. } static int @@ -162,58 +159,63 @@ cmd_debug_all(int argc, char **argv) { if (argc > 0) { val = htoi(argv[1]); - diag_l0_debug = val; - diag_l1_debug = val; - diag_l2_debug = val; - diag_l3_debug = val; - diag_cli_debug = val; + diag_l0_debug_store(val); + diag_l1_debug_store(val); + diag_l2_debug_store(val); + diag_l3_debug_store(val); + diag_cli_debug_store(val); } return cmd_debug_show(1, NULL); return CMD_OK; } - static int cmd_debug_show(UNUSED(int argc), UNUSED(char **argv)) { -/* int layer, val; */ + /* int layer, val; */ printf("Debug values: L0 0x%X, L1 0x%X, L2 0x%X L3 0x%X CLI 0x%X\n", - diag_l0_debug, diag_l1_debug, diag_l2_debug, diag_l3_debug, - diag_cli_debug); + diag_l0_debug_load(), diag_l1_debug_load(), diag_l2_debug_load(), + diag_l3_debug_load(), diag_cli_debug_load()); return CMD_OK; } +// cmd_debug_l0test : run a variety of low-level +// tests, for dumb interfaces. Do not use while connected +// to a vehicle: this sends garbage data on the K-line which +// could interfere with ECUs, although very unlikely. -//cmd_debug_l0test : run a variety of low-level -//tests, for dumb interfaces. Do not use while connected -//to a vehicle: this sends garbage data on the K-line which -//could interfere with ECUs, although very unlikely. - -static int cmd_debug_l0test(int argc, char **argv) { +static int +cmd_debug_l0test(int argc, char **argv) { #define MAX_L0TEST 14 struct diag_l0_device *dl0d = global_dl0d; - unsigned int testnum=0; + unsigned int testnum = 0; - if ((argc <= 1) || (strcmp(argv[1], "?") == 0) || (sscanf(argv[1],"%u", &testnum) != 1)) { - printf("usage: %s [testnum], where testnum is a number between 1 and %d.\n", argv[0], MAX_L0TEST); - printf("you must have done \"set interface dumbt [port]\" and \"set dumbopts\" before proceding.\n"); + if ((argc <= 1) || (strcmp(argv[1], "?") == 0) || + (sscanf(argv[1], "%u", &testnum) != 1)) { + printf("usage: %s [testnum], where testnum is a number between 1 and " + "%d.\n", + argv[0], MAX_L0TEST); + printf("you must have done \"set interface dumbt [port]\" and \"set " + "dumbopts\" before proceding.\n"); printf("Available tests:\n" - "\t1 : slow pulse TXD (K) with diag_tty_break.\n" - "\t2 : fast pulse TXD (K) : send 0x55 @ 10400bps, 5ms interbyte (P4)\n" - "\t10: fast pulse TXD (K) : send 0x55 @ 15000bps, 5ms interbyte (P4)\n" - "\t3 : slow pulse RTS.\n" - "\t4 : slow pulse DTR.\n" - "\t5 : fast pulse TXD (K) with diag_tty_break.\n" - "\t6 : fast pulse TXD (K) with diag_tty_fastbreak.\n" - "\t13: simulate iso14230 fastinit with diag_tty_fastbreak.\n" - "\t7 : simple half duplex removal speed test (10400bps)\n" - "\t14: simple half duplex removal speed test (360bps)\n" - "\t8 : block half duplex removal speed test.\n" - "\t9 : read timeout accuracy check\n" - "\t11: half duplex incomplete read timeout test.\n" - "\t12: diag_tty_write() duration.\n"); + "\t1 : slow pulse TXD (K) with diag_tty_break.\n" + "\t2 : fast pulse TXD (K) : send 0x55 @ 10400bps, 5ms interbyte " + "(P4)\n" + "\t10: fast pulse TXD (K) : send 0x55 @ 15000bps, 5ms interbyte " + "(P4)\n" + "\t3 : slow pulse RTS.\n" + "\t4 : slow pulse DTR.\n" + "\t5 : fast pulse TXD (K) with diag_tty_break.\n" + "\t6 : fast pulse TXD (K) with diag_tty_fastbreak.\n" + "\t13: simulate iso14230 fastinit with diag_tty_fastbreak.\n" + "\t7 : simple half duplex removal speed test (10400bps)\n" + "\t14: simple half duplex removal speed test (360bps)\n" + "\t8 : block half duplex removal speed test.\n" + "\t9 : read timeout accuracy check\n" + "\t11: half duplex incomplete read timeout test.\n" + "\t12: diag_tty_write() duration.\n"); return CMD_OK; } if ((testnum < 1) || (testnum > MAX_L0TEST)) { @@ -240,12 +242,9 @@ static int cmd_debug_l0test(int argc, char **argv) { // to pretend testnum is an L1protocol. Then we can use diag_l2_open to start the // test. - (void) diag_l2_open(dl0d, (int) testnum); + (void)diag_l2_open(dl0d, (int)testnum); - //We don't need to _close anything since DUMBT is designed to "fail", i.e. - //return no new dl0d, etc. + // We don't need to _close anything since DUMBT is designed to "fail", i.e. + // return no new dl0d, etc. return CMD_OK; - - } - diff --git a/scantool/scantool_diag.c b/scantool/scantool_diag.c index 7337bc78..5b45ab2f 100644 --- a/scantool/scantool_diag.c +++ b/scantool/scantool_diag.c @@ -39,7 +39,6 @@ #include "scantool.h" #include "scantool_cli.h" - static int cmd_diag_help(int argc, char **argv); static int cmd_diag_disconnect(int argc, char **argv); @@ -54,42 +53,38 @@ static int cmd_diag_probe(int argc, char **argv); static int cmd_diag_fastprobe(int argc, char **argv); const struct cmd_tbl_entry diag_cmd_table[] = { - { "help", "help [command]", "Gives help for a command", - cmd_diag_help, 0, NULL}, - { "?", "? [command]", "Gives help for a command", - cmd_diag_help, FLAG_HIDDEN, NULL}, - - { "connect", "connect", "Connect to ECU", cmd_diag_connect, 0, NULL}, - - { "disconnect", "disconnect", "Disconnect from ECU", cmd_diag_disconnect, - 0, NULL}, - - { "sendreq", "sendreq [byte0 [byte1 [...]]]", "Send raw data to the ECU and print response", - cmd_diag_sendreq, 0, NULL}, - { "sr", "sendreq [byte0 [byte1 [...]]]", "Send a command to the ECU and print response", - cmd_diag_sendreq, FLAG_HIDDEN, NULL}, - { "read", "read [waittime]", - "Receive some data from the ECU waiting waittime seconds", - cmd_diag_read, 0, NULL}, - { "rx", "read [waittime]", "Receive some data from the ECU", - cmd_diag_read, FLAG_HIDDEN, NULL}, - - { "addl3", "addl3 [protocol]", "Add (start) a L3 protocol", - cmd_diag_addl3, 0, NULL}, - { "reml3", "reml3", "Remove (stop) an L3 protocol", - cmd_diag_reml3, 0, NULL}, - - { "probe", "probe start_addr [stop_addr]", "Scan bus using ISO9141 5 baud init [slow!]", cmd_diag_probe, 0, NULL}, - { "fastprobe", "fastprobe start_addr [stop_addr [func]]", "Scan bus using ISO14230 fast init with physical or functional addressing", cmd_diag_fastprobe, 0, NULL}, - { "up", "up", "Return to previous menu level", - cmd_up, 0, NULL}, - { "quit","quit", "Exit program", - cmd_exit, FLAG_HIDDEN, NULL}, - { "exit", "exit", "Exit program", - cmd_exit, 0, NULL}, - - { NULL, NULL, NULL, NULL, 0, NULL} -}; + {"help", "help [command]", "Gives help for a command", cmd_diag_help, 0, NULL}, + {"?", "? [command]", "Gives help for a command", cmd_diag_help, FLAG_HIDDEN, NULL}, + + {"connect", "connect", "Connect to ECU", cmd_diag_connect, 0, NULL}, + + {"disconnect", "disconnect", "Disconnect from ECU", cmd_diag_disconnect, 0, NULL}, + + {"sendreq", "sendreq [byte0 [byte1 [...]]]", + "Send raw data to the ECU and print response", cmd_diag_sendreq, 0, NULL}, + {"sr", "sendreq [byte0 [byte1 [...]]]", + "Send a command to the ECU and print response", cmd_diag_sendreq, FLAG_HIDDEN, + NULL}, + {"read", "read [waittime]", + "Receive some data from the ECU waiting waittime seconds", cmd_diag_read, 0, + NULL}, + {"rx", "read [waittime]", "Receive some data from the ECU", cmd_diag_read, + FLAG_HIDDEN, NULL}, + + {"addl3", "addl3 [protocol]", "Add (start) a L3 protocol", cmd_diag_addl3, 0, + NULL}, + {"reml3", "reml3", "Remove (stop) an L3 protocol", cmd_diag_reml3, 0, NULL}, + + {"probe", "probe start_addr [stop_addr]", + "Scan bus using ISO9141 5 baud init [slow!]", cmd_diag_probe, 0, NULL}, + {"fastprobe", "fastprobe start_addr [stop_addr [func]]", + "Scan bus using ISO14230 fast init with physical or functional addressing", + cmd_diag_fastprobe, 0, NULL}, + {"up", "up", "Return to previous menu level", cmd_up, 0, NULL}, + {"quit", "quit", "Exit program", cmd_exit, FLAG_HIDDEN, NULL}, + {"exit", "exit", "Exit program", cmd_exit, 0, NULL}, + + {NULL, NULL, NULL, NULL, 0, NULL}}; static int cmd_diag_help(int argc, char **argv) { @@ -107,7 +102,7 @@ cmd_diag_addl3(int argc, char **argv) { if (strcmp(argv[1], "?") == 0) { printf("Valid protocols are: "); - for (i=0; diag_l3_protocols[i] != NULL; i++) { + for (i = 0; diag_l3_protocols[i] != NULL; i++) { printf("%s ", diag_l3_protocols[i]->proto_name); } printf("\n"); @@ -126,12 +121,16 @@ cmd_diag_addl3(int argc, char **argv) { } if (global_l3_conn != NULL) { - fprintf(stderr, FLFMT "Oops : there's a global L3 conn with an invalid global_state ! Report this !\n", FL); + fprintf(stderr, + FLFMT + "Oops : there's a global L3 conn with an invalid global_state ! " + "Report this !\n", + FL); return CMD_FAILED; } - //match specified L3proto with available protos - for (i=0, proto = NULL; diag_l3_protocols[i] != NULL; i++) { + // match specified L3proto with available protos + for (i = 0, proto = NULL; diag_l3_protocols[i] != NULL; i++) { if (strcasecmp(diag_l3_protocols[i]->proto_name, argv[1]) == 0) { proto = diag_l3_protocols[i]->proto_name; break; @@ -139,27 +138,26 @@ cmd_diag_addl3(int argc, char **argv) { } if (proto == NULL) { - printf("No such protocol, use %s ? for list of protocols\n", - argv[0]); + printf("No such protocol, use %s ? for list of protocols\n", argv[0]); return CMD_OK; } - //use the global L2 connection to start an L3 connection. + // use the global L2 connection to start an L3 connection. global_l3_conn = diag_l3_start(proto, global_l2_conn); - if (global_l3_conn !=NULL) { - global_state = STATE_L3ADDED ; + if (global_l3_conn != NULL) { + global_state = STATE_L3ADDED; printf("Done\n"); } else { printf("Failed to add L3 protocol\n"); } - return CMD_OK; } // cmd_diag_reml3 : undoes what diag_addl3 did. -static int cmd_diag_reml3(UNUSED(int argc), UNUSED(char **argv)) { +static int +cmd_diag_reml3(UNUSED(int argc), UNUSED(char **argv)) { int rv; struct diag_l3_conn *old_dl3c = global_l3_conn; @@ -173,22 +171,21 @@ static int cmd_diag_reml3(UNUSED(int argc), UNUSED(char **argv)) { return CMD_FAILED; } - global_l3_conn = global_l3_conn->next; //in case there was more than 1 + global_l3_conn = global_l3_conn->next; // in case there was more than 1 - rv=diag_l3_stop(old_dl3c); + rv = diag_l3_stop(old_dl3c); if (global_l3_conn == NULL) { global_state = STATE_CONNECTED; // we probably still have an L2 // hanging there } - return rv? diag_iseterr(rv):0; + return rv ? diag_iseterr(rv) : 0; } - -//cmd_diag_prob_common [startaddr] [stopaddr] -//This should stop searching at the first succesful init -//and update the global connection +// cmd_diag_prob_common [startaddr] [stopaddr] +// This should stop searching at the first succesful init +// and update the global connection static int cmd_diag_probe_common(int argc, char **argv, int fastflag) { unsigned int start, end, i; @@ -222,8 +219,7 @@ cmd_diag_probe_common(int argc, char **argv, int fastflag) { end = htoi(argv[2]); } - - if (fastflag && argc>=4) { + if (fastflag && argc >= 4) { if (strcasecmp(argv[3], "func") == 0) { funcmode = DIAG_L2_TYPE_FUNCADDR; } @@ -247,7 +243,7 @@ cmd_diag_probe_common(int argc, char **argv, int fastflag) { /* Open interface using hardware type ISO9141 */ rv = diag_l2_open(dl0d, DIAG_L1_ISO9141); if (rv) { - printf("Failed to open hardware interface, error 0x%X",rv); + printf("Failed to open hardware interface, error 0x%X", rv); if (rv == DIAG_ERR_PROTO_NOTSUPP) { printf(", does not support requested L1 protocol\n"); } else if (rv == DIAG_ERR_BADIFADAPTER) { @@ -259,20 +255,19 @@ cmd_diag_probe_common(int argc, char **argv, int fastflag) { } printf("Scanning:\n"); - for (i=start; i<=end; i++) { + for (i = start; i <= end; i++) { printf("\t0x%X ", i); - fflush(stdout) ; + fflush(stdout); if (fastflag) { - d_conn = diag_l2_StartCommunications(dl0d, - DIAG_L2_PROT_ISO14230, - DIAG_L2_TYPE_FASTINIT | funcmode, - global_cfg.speed, (target_type) i, global_cfg.src); - } else { d_conn = diag_l2_StartCommunications( - dl0d, DIAG_L2_PROT_ISO9141, - DIAG_L2_TYPE_SLOWINIT, global_cfg.speed, + dl0d, DIAG_L2_PROT_ISO14230, + DIAG_L2_TYPE_FASTINIT | funcmode, global_cfg.speed, (target_type)i, global_cfg.src); + } else { + d_conn = diag_l2_StartCommunications( + dl0d, DIAG_L2_PROT_ISO9141, DIAG_L2_TYPE_SLOWINIT, + global_cfg.speed, (target_type)i, global_cfg.src); } if (d_conn == NULL) { @@ -298,7 +293,8 @@ cmd_diag_probe_common(int argc, char **argv, int fastflag) { /* Now read some data */ - rv = 0; gotsome = 0; + rv = 0; + gotsome = 0; while (rv >= 0) { rv = diag_l2_recv(d_conn, 100, l2raw_data_rcv, NULL); if (rv > 0) { @@ -312,8 +308,8 @@ cmd_diag_probe_common(int argc, char **argv, int fastflag) { } return CMD_OK; - } //for addresses - //Failed => clean up + } // for addresses + // Failed => clean up diag_l2_close(dl0d); printf("\n"); return CMD_OK; @@ -329,7 +325,6 @@ cmd_diag_fastprobe(int argc, char **argv) { return cmd_diag_probe_common(argc, argv, 1); } - /* * Generic init, using parameters set by user. * Currently only called from cmd_diag_connect; @@ -367,13 +362,14 @@ do_l2_generic_start(void) { flags = 0; } - flags |= (global_cfg.initmode & DIAG_L2_TYPE_INITMASK) ; + flags |= (global_cfg.initmode & DIAG_L2_TYPE_INITMASK); - d_conn = diag_l2_StartCommunications(dl0d, global_cfg.L2proto, - flags, global_cfg.speed, global_cfg.tgt, global_cfg.src); + d_conn = diag_l2_StartCommunications(dl0d, global_cfg.L2proto, flags, + global_cfg.speed, global_cfg.tgt, + global_cfg.src); if (d_conn == NULL) { - rv=diag_geterr(); + rv = diag_geterr(); diag_l2_close(dl0d); return diag_iseterr(rv); } @@ -385,10 +381,8 @@ do_l2_generic_start(void) { return 0; } - - -//cmd_diag_connect : attempt to connect to ECU -//using the current global l2proto, l1proto, etc. +// cmd_diag_connect : attempt to connect to ECU +// using the current global l2proto, l1proto, etc. static int cmd_diag_connect(UNUSED(int argc), UNUSED(char **argv)) { int rv; @@ -403,7 +397,7 @@ cmd_diag_connect(UNUSED(int argc), UNUSED(char **argv)) { } rv = do_l2_generic_start(); - if (rv==0) { + if (rv == 0) { printf("Connection to ECU established!\n"); global_state = STATE_CONNECTED; } else { @@ -416,9 +410,8 @@ cmd_diag_connect(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - -//Currently, this stops + removes the current global L3 conn. -//If there are no more L3 conns, also stop + close the global L2 conn. +// Currently, this stops + removes the current global L3 conn. +// If there are no more L3 conns, also stop + close the global L2 conn. static int cmd_diag_disconnect(UNUSED(int argc), UNUSED(char **argv)) { if (argc > 1) { @@ -431,7 +424,7 @@ cmd_diag_disconnect(UNUSED(int argc), UNUSED(char **argv)) { if (global_state >= STATE_L3ADDED) { /* Close L3 protocol */ - cmd_diag_reml3(0,NULL); + cmd_diag_reml3(0, NULL); } if (global_l3_conn == NULL) { @@ -443,7 +436,7 @@ cmd_diag_disconnect(UNUSED(int argc), UNUSED(char **argv)) { global_state = STATE_IDLE; } else { printf("There is another active L3 connection : %p\n : %s", - (void *) global_l3_conn, global_l3_conn->d_l3_proto->proto_name); + (void *)global_l3_conn, global_l3_conn->d_l3_proto->proto_name); printf("Run disconnect again to close it.\n"); return CMD_OK; } @@ -451,7 +444,6 @@ cmd_diag_disconnect(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - static int cmd_diag_read(int argc, char **argv) { unsigned int timeout = 0; @@ -467,12 +459,11 @@ cmd_diag_read(int argc, char **argv) { if (global_state < STATE_L3ADDED) { /* No L3 protocol, do L2 stuff */ - (void)diag_l2_recv(global_l2_conn, timeout, l2raw_data_rcv, - NULL); + (void)diag_l2_recv(global_l2_conn, timeout, l2raw_data_rcv, NULL); } else { (void)diag_l3_recv(global_l3_conn, timeout, j1979_data_rcv, - (void *)&_RQST_HANDLE_WATCH); + (void *)&_RQST_HANDLE_WATCH); } return CMD_OK; } @@ -482,9 +473,9 @@ cmd_diag_read(int argc, char **argv) { */ static int cmd_diag_sendreq(int argc, char **argv) { - uint8_t data[MAXRBUF]; - unsigned int i,j,len; - int rv; + uint8_t data[MAXRBUF]; + unsigned int i, j, len; + int rv; if (argc < 2) { printf("Too few arguments\n"); @@ -502,19 +493,16 @@ cmd_diag_sendreq(int argc, char **argv) { memset(data, 0, sizeof(data)); - for (i=1, j=0; (i < (unsigned int) argc) && (i < sizeof(data)); i++, j++) { - data[j] = (uint8_t) htoi(argv[i]); + for (i = 1, j = 0; (i < (unsigned int)argc) && (i < sizeof(data)); i++, j++) { + data[j] = (uint8_t)htoi(argv[i]); } - len = j ; - + len = j; if (global_state < STATE_L3ADDED) { - rv = l2_do_send( global_l2_conn, data, len, - (void *)&_RQST_HANDLE_DECODE); + rv = l2_do_send(global_l2_conn, data, len, (void *)&_RQST_HANDLE_DECODE); } else { /* Send data with handle to tell callback to print results */ - rv = l3_do_send( global_l3_conn, data, len, - (void *)&_RQST_HANDLE_DECODE); + rv = l3_do_send(global_l3_conn, data, len, (void *)&_RQST_HANDLE_DECODE); } if (rv != 0) { diff --git a/scantool/scantool_dyno.c b/scantool/scantool_dyno.c index 5e4dcebc..2051c35a 100644 --- a/scantool/scantool_dyno.c +++ b/scantool/scantool_dyno.c @@ -26,7 +26,6 @@ * CLI routines - dyno subcommand */ - #include "diag.h" #include "diag_err.h" #include "diag_os.h" @@ -40,13 +39,10 @@ /* uncomment this to make fake dyno (to test dyno with disconnected ECU) */ /* #define DYNO_DEBUG 1 */ - #ifdef DYNO_DEBUG - #include //for fake_loss_measure_data() +# include //for fake_loss_measure_data() #endif - - dyno_result *dyno_results; int dyno_nb_results; @@ -63,44 +59,36 @@ static int cmd_dyno_save(int argc, char **argv); void reset_results(void); const struct cmd_tbl_entry dyno_cmd_table[] = { - { "help", "help [command]", "Gives help for a command", - cmd_dyno_help, 0, NULL}, - { "?", "? [command]", "Gives help for a command", - cmd_dyno_help, FLAG_HIDDEN, NULL}, - - { "mass", "mass [mass]", "Step 1 : Shows/Sets the mass of the vehicle", - cmd_dyno_mass, 0, NULL}, - { "loss", "loss", "Step 2 : Determines power lost by aerodynamic and friction forces", - cmd_dyno_loss, 0, NULL}, - { "setloss", "setloss [d] [f]", "Manually enter aerodynamic and friction forces parameters", - cmd_dyno_setloss, 0, NULL}, - { "run", "run", "Step 3 : Run dyno", - cmd_dyno_run, 0, NULL}, - { "measures", "measures", "Display run measures", - cmd_dyno_measures, 0, NULL}, - { "result", "result", "Display run results", - cmd_dyno_result, 0, NULL}, - { "graph", "graph", "Display run graphs", - cmd_dyno_graph, 0, NULL}, - { "save", "save [filename]", "Save measures and results in a file", - cmd_dyno_save, 0, NULL}, - - { "up", "up", "Return to previous menu level", - cmd_up, 0, NULL}, - { "quit","quit", "Exit program", - cmd_exit, FLAG_HIDDEN, NULL}, - { "exit", "exit", "Exit program", - cmd_exit, 0, NULL}, - - { NULL, NULL, NULL, NULL, 0, NULL} -}; - + {"help", "help [command]", "Gives help for a command", cmd_dyno_help, 0, NULL}, + {"?", "? [command]", "Gives help for a command", cmd_dyno_help, FLAG_HIDDEN, NULL}, + + {"mass", "mass [mass]", "Step 1 : Shows/Sets the mass of the vehicle", + cmd_dyno_mass, 0, NULL}, + {"loss", "loss", + "Step 2 : Determines power lost by aerodynamic and friction forces", + cmd_dyno_loss, 0, NULL}, + {"setloss", "setloss [d] [f]", + "Manually enter aerodynamic and friction forces parameters", cmd_dyno_setloss, 0, + NULL}, + {"run", "run", "Step 3 : Run dyno", cmd_dyno_run, 0, NULL}, + {"measures", "measures", "Display run measures", cmd_dyno_measures, 0, NULL}, + {"result", "result", "Display run results", cmd_dyno_result, 0, NULL}, + {"graph", "graph", "Display run graphs", cmd_dyno_graph, 0, NULL}, + {"save", "save [filename]", "Save measures and results in a file", cmd_dyno_save, + 0, NULL}, + + {"up", "up", "Return to previous menu level", cmd_up, 0, NULL}, + {"quit", "quit", "Exit program", cmd_exit, FLAG_HIDDEN, NULL}, + {"exit", "exit", "Exit program", cmd_exit, 0, NULL}, + + {NULL, NULL, NULL, NULL, 0, NULL}}; /* * Show/Sets the mass of the vehicle */ -static int cmd_dyno_mass(int argc, char **argv) { - int mass=0; +static int +cmd_dyno_mass(int argc, char **argv) { + int mass = 0; if (argc > 1) { mass = htoi(argv[1]); @@ -119,27 +107,29 @@ static int cmd_dyno_mass(int argc, char **argv) { * Functions to measure data * ******************************************************************************/ -#define DYNDATA_1(p, n, d) (d[p].data[n]) -#define DYNDATA_2(p, n, d) (DYNDATA_1(p, n, d) * 256 + DYNDATA_1(p, n+1, d)) -#define RPM_PID (0x0c) -#define RPM_DATA(d) (DYNDATA_2(RPM_PID, 2, d)*0.25) -#define SPEED_PID (0x0d) -#define SPEED_DATA(d) (DYNDATA_1(SPEED_PID, 2, d) * 10000./36.) /* m/s * 1000 */ +#define DYNDATA_1(p, n, d) (d[p].data[n]) +#define DYNDATA_2(p, n, d) (DYNDATA_1(p, n, d) * 256 + DYNDATA_1(p, n + 1, d)) +#define RPM_PID (0x0c) +#define RPM_DATA(d) (DYNDATA_2(RPM_PID, 2, d) * 0.25) +#define SPEED_PID (0x0d) +#define SPEED_DATA(d) (DYNDATA_1(SPEED_PID, 2, d) * 10000. / 36.) /* m/s * 1000 */ -#define SPEED_ISO_TO_KMH(_speed_) ((_speed_)*36/10000) +#define SPEED_ISO_TO_KMH(_speed_) ((_speed_)*36 / 10000) /* measure speed */ // return <0 if error -static int measure_data(uint8_t data_pid, ecu_data *ep) { +static int +measure_data(uint8_t data_pid, ecu_data *ep) { int rv; if (global_l3_conn == NULL) { - fprintf(stderr, FLFMT "Error: there must be an active L3 connection!\n", FL); + fprintf(stderr, FLFMT "Error: there must be an active L3 connection!\n", + FL); return DIAG_ERR_GENERAL; } /* measure */ - rv = l3_do_j1979_rqst(global_l3_conn, 0x1, data_pid, 0x00, - 0x00, 0x00, 0x00, 0x00, (void *)&_RQST_HANDLE_NORMAL); + rv = l3_do_j1979_rqst(global_l3_conn, 0x1, data_pid, 0x00, 0x00, 0x00, 0x00, 0x00, + (void *)&_RQST_HANDLE_NORMAL); if (rv < 0) { return rv; } @@ -154,116 +144,155 @@ static int measure_data(uint8_t data_pid, ecu_data *ep) { return DYNDATA_1(data_pid, 2, ep->mode1_data); } - #ifdef DYNO_DEBUG int counter; -unsigned long tv0d; /* measuring time */ +unsigned long tv0d; /* measuring time */ /* fake loss measures */ -int fake_loss_measure_data() { +int +fake_loss_measure_data() { unsigned long tv; unsigned long elapsed; /* elapsed time */ int speed; if (counter == 0) { - tv0d=diag_os_getms(); + tv0d = diag_os_getms(); } diag_os_millisleep(250); /* get elapsed time */ - tv=diag_os_getms(); + tv = diag_os_getms(); elapsed = tv - tv0d; + // I think we're supposed to simulate an exponential decreasing + // function ; speed = b * e^(elapsed / a). + float a = -62810; + float b = 25027; - //I think we're supposed to simulate an exponential decreasing - //function ; speed = b * e^(elapsed / a). - float a= -62810; - float b= 25027; - - return (int) (b * exp(elapsed / a)); - + return (int)(b * exp(elapsed / a)); elapsed += 11000; - //XXX This was a most interesting lookup table!! Can be deleted soon. - if (elapsed < 11983) speed = 89*10000/36; - else if (elapsed < 12723) speed = 88*10000/36; - else if (elapsed < 13473) speed = 87*10000/36; - else if (elapsed < 14713) speed = 85*10000/36; - else if (elapsed < 15713) speed = 84*10000/36; - else if (elapsed < 16213) speed = 83*10000/36; - else if (elapsed < 16963) speed = 82*10000/36; - else if (elapsed < 17463) speed = 81*10000/36; - else if (elapsed < 18463) speed = 80*10000/36; - else if (elapsed < 19463) speed = 79*10000/36; - else if (elapsed < 20213) speed = 78*10000/36; - else if (elapsed < 20963) speed = 77*10000/36; - else if (elapsed < 22463) speed = 76*10000/36; - else if (elapsed < 22963) speed = 75*10000/36; - else if (elapsed < 23713) speed = 74*10000/36; - else if (elapsed < 25213) speed = 73*10000/36; - else if (elapsed < 26453) speed = 72*10000/36; - else if (elapsed < 27203) speed = 71*10000/36; - else if (elapsed < 27953) speed = 70*10000/36; - else if (elapsed < 29193) speed = 69*10000/36; - else if (elapsed < 29943) speed = 68*10000/36; - else if (elapsed < 30693) speed = 67*10000/36; - else if (elapsed < 32183) speed = 66*10000/36; - else if (elapsed < 32933) speed = 65*10000/36; - else if (elapsed < 33683) speed = 64*10000/36; - else if (elapsed < 34683) speed = 63*10000/36; - else if (elapsed < 35433) speed = 62*10000/36; - else if (elapsed < 36433) speed = 61*10000/36; - else if (elapsed < 37183) speed = 60*10000/36; - else if (elapsed < 38433) speed = 59*10000/36; - else if (elapsed < 39433) speed = 58*10000/36; - else if (elapsed < 40183) speed = 57*10000/36; - else if (elapsed < 40683) speed = 56*10000/36; - else if (elapsed < 42183) speed = 55*10000/36; - else if (elapsed < 43183) speed = 54*10000/36; - else if (elapsed < 44683) speed = 53*10000/36; - else if (elapsed < 45933) speed = 52*10000/36; - else if (elapsed < 47183) speed = 51*10000/36; - else if (elapsed < 48183) speed = 50*10000/36; - else if (elapsed < 49433) speed = 49*10000/36; - else speed = 48*10000/36; - - counter++; - - return speed; + // XXX This was a most interesting lookup table!! Can be deleted soon. + if (elapsed < 11983) + speed = 89 * 10000 / 36; + else if (elapsed < 12723) + speed = 88 * 10000 / 36; + else if (elapsed < 13473) + speed = 87 * 10000 / 36; + else if (elapsed < 14713) + speed = 85 * 10000 / 36; + else if (elapsed < 15713) + speed = 84 * 10000 / 36; + else if (elapsed < 16213) + speed = 83 * 10000 / 36; + else if (elapsed < 16963) + speed = 82 * 10000 / 36; + else if (elapsed < 17463) + speed = 81 * 10000 / 36; + else if (elapsed < 18463) + speed = 80 * 10000 / 36; + else if (elapsed < 19463) + speed = 79 * 10000 / 36; + else if (elapsed < 20213) + speed = 78 * 10000 / 36; + else if (elapsed < 20963) + speed = 77 * 10000 / 36; + else if (elapsed < 22463) + speed = 76 * 10000 / 36; + else if (elapsed < 22963) + speed = 75 * 10000 / 36; + else if (elapsed < 23713) + speed = 74 * 10000 / 36; + else if (elapsed < 25213) + speed = 73 * 10000 / 36; + else if (elapsed < 26453) + speed = 72 * 10000 / 36; + else if (elapsed < 27203) + speed = 71 * 10000 / 36; + else if (elapsed < 27953) + speed = 70 * 10000 / 36; + else if (elapsed < 29193) + speed = 69 * 10000 / 36; + else if (elapsed < 29943) + speed = 68 * 10000 / 36; + else if (elapsed < 30693) + speed = 67 * 10000 / 36; + else if (elapsed < 32183) + speed = 66 * 10000 / 36; + else if (elapsed < 32933) + speed = 65 * 10000 / 36; + else if (elapsed < 33683) + speed = 64 * 10000 / 36; + else if (elapsed < 34683) + speed = 63 * 10000 / 36; + else if (elapsed < 35433) + speed = 62 * 10000 / 36; + else if (elapsed < 36433) + speed = 61 * 10000 / 36; + else if (elapsed < 37183) + speed = 60 * 10000 / 36; + else if (elapsed < 38433) + speed = 59 * 10000 / 36; + else if (elapsed < 39433) + speed = 58 * 10000 / 36; + else if (elapsed < 40183) + speed = 57 * 10000 / 36; + else if (elapsed < 40683) + speed = 56 * 10000 / 36; + else if (elapsed < 42183) + speed = 55 * 10000 / 36; + else if (elapsed < 43183) + speed = 54 * 10000 / 36; + else if (elapsed < 44683) + speed = 53 * 10000 / 36; + else if (elapsed < 45933) + speed = 52 * 10000 / 36; + else if (elapsed < 47183) + speed = 51 * 10000 / 36; + else if (elapsed < 48183) + speed = 50 * 10000 / 36; + else if (elapsed < 49433) + speed = 49 * 10000 / 36; + else + speed = 48 * 10000 / 36; + + counter++; + + return speed; } int counter2; /* fake run measures */ -int fake_run_measure_data(int data_pid) { - int rpm; +int +fake_run_measure_data(int data_pid) { + int rpm; - diag_os_millisleep(250); + diag_os_millisleep(250); - rpm = 1000 + counter2 * 200; - if (counter2 < 5500/200) - counter2++; - else - counter2--; + rpm = 1000 + counter2 * 200; + if (counter2 < 5500 / 200) + counter2++; + else + counter2--; - if (data_pid == RPM_PID) - return rpm; - else if (data_pid == SPEED_PID) - return rpm * (9000*100/6000) / 36; + if (data_pid == RPM_PID) + return rpm; + else if (data_pid == SPEED_PID) + return rpm * (9000 * 100 / 6000) / 36; return 0; } -#define LOSS_MEASURE_DATA(_pid_, _ep_) fake_loss_measure_data() -#define RUN_MEASURE_DATA(_pid_, _ep_) fake_run_measure_data(_pid_) +# define LOSS_MEASURE_DATA(_pid_, _ep_) fake_loss_measure_data() +# define RUN_MEASURE_DATA(_pid_, _ep_) fake_run_measure_data(_pid_) #else /* DYNO_DEBUG */ -#define LOSS_MEASURE_DATA(_pid_, _ep_) measure_data(_pid_, _ep_) -#define RUN_MEASURE_DATA(_pid_, _ep_) measure_data(_pid_, _ep_) +# define LOSS_MEASURE_DATA(_pid_, _ep_) measure_data(_pid_, _ep_) +# define RUN_MEASURE_DATA(_pid_, _ep_) measure_data(_pid_, _ep_) #endif - /***************************************************************************** * Measuring loss function * *****************************************************************************/ @@ -275,7 +304,8 @@ int dyno_loss_done; * Determine power lost by aerodynamic and friction forces */ -static int cmd_dyno_loss(UNUSED(int argc), UNUSED(char **argv)) { +static int +cmd_dyno_loss(UNUSED(int argc), UNUSED(char **argv)) { ecu_data *ep; int speed; /* measured speed */ @@ -285,23 +315,27 @@ static int cmd_dyno_loss(UNUSED(int argc), UNUSED(char **argv)) { int elapsed; /* elapsed time */ int i, length; /* length of printed string */ - int nb = 0; /* number of measures */ + int nb = 0; /* number of measures */ - //make sure we have an L3 connection first ! + // make sure we have an L3 connection first ! if (global_l3_conn == NULL) { - fprintf(stderr, FLFMT "Error: there must be an active L3 connection!\n", FL); + fprintf(stderr, FLFMT "Error: there must be an active L3 connection!\n", + FL); return CMD_FAILED; } /* Check mass */ if (dyno_get_mass() <= 0) { - printf("The mass of the vehicle has not been set, please set the mass first\n"); + printf("The mass of the vehicle has not been set, please set the mass " + "first\n"); return CMD_OK; } /* Show instructions */ - printf("To proceed loss determination, reach the maximum speed you will reach during\n"); - printf("dyno, then push in the clutch, leaving the car in gear. Allow the car to coast\n"); + printf("To proceed loss determination, reach the maximum speed you will reach " + "during\n"); + printf("dyno, then push in the clutch, leaving the car in gear. Allow the car to " + "coast\n"); printf("down to the lowest possible speed. Press ENTER when finished.\n"); printf("\n"); wait_enter("Press ENTER when ready... "); @@ -310,8 +344,8 @@ static int cmd_dyno_loss(UNUSED(int argc), UNUSED(char **argv)) { /* Reset data */ dyno_loss_reset(); /* dyno data */ reset_results(); - tv0=diag_os_getms(); /* initial time */ - ep = ecu_info; /* ECU data */ + tv0 = diag_os_getms(); /* initial time */ + ep = ecu_info; /* ECU data */ /* exclude 1st measure */ speed_previous = LOSS_MEASURE_DATA(SPEED_PID, ep); /* m/s * 1000 */ @@ -320,7 +354,8 @@ static int cmd_dyno_loss(UNUSED(int argc), UNUSED(char **argv)) { return CMD_FAILED; } - printf("Starting loss determination (max speed=%d km/h)\n", SPEED_ISO_TO_KMH(speed_previous)); + printf("Starting loss determination (max speed=%d km/h)\n", + SPEED_ISO_TO_KMH(speed_previous)); printf("Number of measures : 0"); length = 1; @@ -333,11 +368,10 @@ static int cmd_dyno_loss(UNUSED(int argc), UNUSED(char **argv)) { break; } - /* get elapsed time */ - tv=diag_os_getms(); - elapsed = (int) (tv - tv0); + tv = diag_os_getms(); + elapsed = (int)(tv - tv0); if (speed < speed_previous) { /* Add measure */ @@ -349,7 +383,8 @@ static int cmd_dyno_loss(UNUSED(int argc), UNUSED(char **argv)) { if (pressed_enter() != 0) { /* ENTER pressed : stops */ - printf("Number of measures : %d (min speed=%d km/h)\n", nb, SPEED_ISO_TO_KMH(speed)); + printf("Number of measures : %d (min speed=%d km/h)\n", nb, + SPEED_ISO_TO_KMH(speed)); break; } if (speed_previous == speed) { /* measure added: update display */ @@ -359,18 +394,19 @@ static int cmd_dyno_loss(UNUSED(int argc), UNUSED(char **argv)) { } /* Display new measure */ - length = printf("%d (speed=%d km/h, d=%5.5f, f=%4.2f)\t ", - nb, SPEED_ISO_TO_KMH(speed), dyno_loss_get_d(), dyno_loss_get_f()); + length = printf("%d (speed=%d km/h, d=%5.5f, f=%4.2f)\t ", nb, + SPEED_ISO_TO_KMH(speed), dyno_loss_get_d(), + dyno_loss_get_f()); fflush(stdout); /* force displaying now (may slow down dyno...) */ } } /* display dyno time */ - //elapsed = MILLIS(tv) - MILLIS(tv0); - tv=diag_os_getms(); - elapsed= (int) (tv - tv0); + // elapsed = MILLIS(tv) - MILLIS(tv0); + tv = diag_os_getms(); + elapsed = (int)(tv - tv0); printf("d=%5.5f, f=%4.2f\n", dyno_loss_get_d(), dyno_loss_get_f()); - printf("Loss determination time : %ds.\n", (elapsed/1000)); + printf("Loss determination time : %ds.\n", (elapsed / 1000)); printf("\n"); @@ -383,7 +419,8 @@ static int cmd_dyno_loss(UNUSED(int argc), UNUSED(char **argv)) { /* * Manually enter aerodynamic and friction forces d and f parameters */ -static int cmd_dyno_setloss(int argc, char **argv) { +static int +cmd_dyno_setloss(int argc, char **argv) { if (argc > 1) { int assigned; double d; @@ -421,20 +458,21 @@ static int cmd_dyno_setloss(int argc, char **argv) { * Run dyno */ -static int cmd_dyno_run(UNUSED(int argc), UNUSED(char **argv)) { +static int +cmd_dyno_run(UNUSED(int argc), UNUSED(char **argv)) { ecu_data *ep; - int speed; /* measured speed */ - int rpm; /* measured rpm */ + int speed; /* measured speed */ + int rpm; /* measured rpm */ int rpm_previous = 0; /* previous rpm */ - unsigned long tv0, tv; /* measuring time */ - int elapsed; /* elapsed time (ms) */ + unsigned long tv0, tv; /* measuring time */ + int elapsed; /* elapsed time (ms) */ int i, length = 0; /* length of printed string */ - int nb = 0; /* number of measures */ + int nb = 0; /* number of measures */ - //make sure we're connected ! + // make sure we're connected ! if (global_l3_conn == NULL) { fprintf(stderr, FLFMT "No active L3 connection !\n", FL); return CMD_FAILED; @@ -442,13 +480,15 @@ static int cmd_dyno_run(UNUSED(int argc), UNUSED(char **argv)) { /* Check mass */ if (dyno_get_mass() <= 0) { - printf("The mass of the vehicle has not been set, please set the mass first\n"); + printf("The mass of the vehicle has not been set, please set the mass " + "first\n"); return CMD_OK; } /* Check mass */ if (dyno_loss_done <= 0) { - printf("The loss determination has not been done, please use command loss or setloss first\n"); + printf("The loss determination has not been done, please use command loss " + "or setloss first\n"); return CMD_OK; } @@ -464,8 +504,8 @@ static int cmd_dyno_run(UNUSED(int argc), UNUSED(char **argv)) { dyno_reset(); /* dyno data */ reset_results(); - tv0=diag_os_getms(); /* initial time */ - ep = ecu_info; /* ECU data */ + tv0 = diag_os_getms(); /* initial time */ + ep = ecu_info; /* ECU data */ /* Measures */ while (1) { @@ -477,7 +517,6 @@ static int cmd_dyno_run(UNUSED(int argc), UNUSED(char **argv)) { break; } - if (rpm_previous == 0) { /* this is the first measure */ printf("Starting dyno (min rpm=%d)\n", rpm); @@ -491,8 +530,8 @@ static int cmd_dyno_run(UNUSED(int argc), UNUSED(char **argv)) { } /* get elapsed time */ - tv=diag_os_getms(); - elapsed = (int) (tv - tv0); + tv = diag_os_getms(); + elapsed = (int)(tv - tv0); /* Add measure */ dyno_add_measure(elapsed, rpm); @@ -512,7 +551,7 @@ static int cmd_dyno_run(UNUSED(int argc), UNUSED(char **argv)) { /* measure gear ratio */ rpm_previous = rpm; speed = RUN_MEASURE_DATA(SPEED_PID, ep); /* m/s * 1000 */ - rpm = RUN_MEASURE_DATA(RPM_PID, ep); + rpm = RUN_MEASURE_DATA(RPM_PID, ep); if ((speed < 0) || (rpm < 0)) { printf("invalid RUN_MEASURE_DATA result !\n"); @@ -521,22 +560,22 @@ static int cmd_dyno_run(UNUSED(int argc), UNUSED(char **argv)) { dyno_set_gear(speed, (rpm_previous + rpm) / 2); /* display dyno time */ - tv=diag_os_getms(); - elapsed = (int) (tv - tv0); - printf("Dyno time : %ds.\n", (elapsed/1000)); + tv = diag_os_getms(); + elapsed = (int)(tv - tv0); + printf("Dyno time : %ds.\n", (elapsed / 1000)); printf("\n"); return CMD_OK; } - /***************************************************************************** * Displaying measures and results functions * *****************************************************************************/ /* Get measures for specified type */ -static void get_measures(dyno_measure **measures, int *nb_measures) { +static void +get_measures(dyno_measure **measures, int *nb_measures) { /* allocate memory */ (*nb_measures) = dyno_get_nb_measures(); if ((*nb_measures) == 0) { @@ -551,17 +590,17 @@ static void get_measures(dyno_measure **measures, int *nb_measures) { } /* Display given measures */ -static void display_measures(dyno_measure *measures, int nb_measures) { +static void +display_measures(dyno_measure *measures, int nb_measures) { int i; - for (i=0; i max_power) { max_power = results[i].power; @@ -607,22 +648,23 @@ static void display_results(dyno_result *results, int nb) { max_torque_i = i; } - if (((i+1) % 22) == 0) { + if (((i + 1) % 22) == 0) { wait_enter("Press ENTER to continue... "); } } printf("\n"); - printf("Max power : %d ch (at %d RPM)\n", - results[max_power_i].power_ch, results[max_power_i].rpm); - printf("Max torque : %d Nm (at %d RPM)\n", - results[max_torque_i].torque, results[max_torque_i].rpm); + printf("Max power : %d ch (at %d RPM)\n", results[max_power_i].power_ch, + results[max_power_i].rpm); + printf("Max torque : %d Nm (at %d RPM)\n", results[max_torque_i].torque, + results[max_torque_i].rpm); printf("\n"); } #define DYNO_GRAPH_HEIGHT 21 /* Display graphs */ -static void display_graphs(dyno_result *results, int nb) { +static void +display_graphs(dyno_result *results, int nb) { int row, col, step; int max_power_i = 0; @@ -631,7 +673,7 @@ static void display_graphs(dyno_result *results, int nb) { int max_torque = 0; /* Detect maximums */ - for (col=0; col max_power) { max_power = results[col].power; max_power_i = col; @@ -647,8 +689,8 @@ static void display_graphs(dyno_result *results, int nb) { /* Displaying torque */ printf("Torque :\n"); - for (row=DYNO_GRAPH_HEIGHT-1; row>=0; row--) { - for (col=0; col= 0; row--) { + for (col = 0; col < nb; col += step) { if (results[col].torque * DYNO_GRAPH_HEIGHT > results[max_torque_i].torque * row) { printf("*"); @@ -668,8 +710,8 @@ static void display_graphs(dyno_result *results, int nb) { /* Displaying power */ printf("Power :\n"); - for (row=DYNO_GRAPH_HEIGHT-1; row>=0; row--) { - for (col=0; col= 0; row--) { + for (col = 0; col < nb; col += step) { if (results[col].power * DYNO_GRAPH_HEIGHT > results[max_power_i].power * row) { printf("*"); @@ -683,7 +725,8 @@ static void display_graphs(dyno_result *results, int nb) { } /* Get the results in global vars */ -static void get_results(void) { +static void +get_results(void) { /* allocating memory for the results table */ if (dyno_results == NULL) { dyno_nb_results = dyno_get_nb_results(); @@ -703,7 +746,8 @@ static void get_results(void) { } /* Reset results */ -void reset_results(void) { +void +reset_results(void) { if (dyno_results != NULL) { free(dyno_results); } @@ -715,7 +759,8 @@ void reset_results(void) { * Display dyno results */ -static int cmd_dyno_result(UNUSED(int argc), UNUSED(char **argv)) { +static int +cmd_dyno_result(UNUSED(int argc), UNUSED(char **argv)) { get_results(); /* Check data */ @@ -732,7 +777,8 @@ static int cmd_dyno_result(UNUSED(int argc), UNUSED(char **argv)) { * Display dyno graphs */ -static int cmd_dyno_graph(UNUSED(int argc), UNUSED(char **argv)) { +static int +cmd_dyno_graph(UNUSED(int argc), UNUSED(char **argv)) { get_results(); /* Check data */ @@ -745,7 +791,6 @@ static int cmd_dyno_graph(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - /***************************************************************************** * Saving functions * *****************************************************************************/ @@ -753,7 +798,8 @@ static int cmd_dyno_graph(UNUSED(int argc), UNUSED(char **argv)) { /* * Save dyno measures and results to a file */ -static int cmd_dyno_save(int argc, char **argv) { +static int +cmd_dyno_save(int argc, char **argv) { char *filename; int rv; @@ -765,7 +811,6 @@ static int cmd_dyno_save(int argc, char **argv) { return CMD_OK; } - if (argc > 1) { /* Get filename from command arguments */ size_t length = strlen(argv[1]); @@ -788,9 +833,9 @@ static int cmd_dyno_save(int argc, char **argv) { } /* Remove pending "\n" and "\r", if any */ - while ((filename[strlen(filename)-1] == '\n') || - (filename[strlen(filename)-1] == '\r')) { - filename[strlen(filename)-1] = '\0'; + while ((filename[strlen(filename) - 1] == '\n') || + (filename[strlen(filename) - 1] == '\r')) { + filename[strlen(filename) - 1] = '\0'; } } @@ -801,7 +846,6 @@ static int cmd_dyno_save(int argc, char **argv) { return CMD_OK; } - /* Display help */ static int cmd_dyno_help(int argc, char **argv) { diff --git a/scantool/scantool_obd.c b/scantool/scantool_obd.c index 2e18bfab..758c663f 100644 --- a/scantool/scantool_obd.c +++ b/scantool/scantool_obd.c @@ -17,14 +17,12 @@ #include "scantool_cli.h" #include "scantool_obd.h" - - -//cmd_watch : this creates a diag_l3_conn +// cmd_watch : this creates a diag_l3_conn static int cmd_watch(int argc, char **argv) { int rv; struct diag_l2_conn *d_l2_conn; - struct diag_l3_conn *d_l3_conn=NULL; + struct diag_l3_conn *d_l3_conn = NULL; struct diag_l0_device *dl0d = global_dl0d; bool rawmode = 0; bool nodecode = 0; @@ -72,13 +70,13 @@ cmd_watch(int argc, char **argv) { return CMD_FAILED; } if (rawmode) { - d_l2_conn = diag_l2_StartCommunications(dl0d, DIAG_L2_PROT_RAW, - 0, global_cfg.speed, - global_cfg.tgt, - global_cfg.src); + d_l2_conn = diag_l2_StartCommunications(dl0d, DIAG_L2_PROT_RAW, 0, + global_cfg.speed, global_cfg.tgt, + global_cfg.src); } else { - d_l2_conn = diag_l2_StartCommunications(dl0d, global_cfg.L2proto, - DIAG_L2_TYPE_MONINIT, global_cfg.speed, global_cfg.tgt, global_cfg.src); + d_l2_conn = diag_l2_StartCommunications( + dl0d, global_cfg.L2proto, DIAG_L2_TYPE_MONINIT, global_cfg.speed, + global_cfg.tgt, global_cfg.src); } if (d_l2_conn == NULL) { @@ -86,8 +84,8 @@ cmd_watch(int argc, char **argv) { diag_l2_close(dl0d); return CMD_FAILED; } - //here we have a valid d_l2_conn over dl0d. - (void) diag_os_ipending(); + // here we have a valid d_l2_conn over dl0d. + (void)diag_os_ipending(); if (!rawmode) { /* Put the SAE J1979 stack on top of the ISO device */ @@ -111,12 +109,10 @@ cmd_watch(int argc, char **argv) { } if (d_l3_conn != NULL) { - rv = diag_l3_recv(d_l3_conn, 10000, - j1979_watch_rcv, - (nodecode) ? NULL:(void *)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); + rv = diag_l2_recv(d_l2_conn, 10000, j1979_watch_rcv, NULL); } if (rv == 0) { continue; @@ -126,7 +122,7 @@ cmd_watch(int argc, char **argv) { } } } else { - //rawmode + // rawmode /* * And just read stuff, callback routine will print out the data */ @@ -136,8 +132,8 @@ cmd_watch(int argc, char **argv) { break; } - rv = diag_l2_recv(d_l2_conn, 10000, - j1979_data_rcv, (void *)&_RQST_HANDLE_WATCH); + rv = diag_l2_recv(d_l2_conn, 10000, j1979_data_rcv, + (void *)&_RQST_HANDLE_WATCH); if (rv == 0) { continue; } @@ -158,7 +154,6 @@ cmd_watch(int argc, char **argv) { return CMD_OK; } - /* * Print the monitorable data out, use SI units by default, or "english" * units @@ -170,20 +165,19 @@ print_current_data(bool english) { unsigned int i; unsigned int j; - printf("%-30.30s %-15.15s FreezeFrame\n", - "Parameter", "Current"); + printf("%-30.30s %-15.15s FreezeFrame\n", "Parameter", "Current"); - for (j = 0 ; get_pid(j) != NULL ; j++) { - const struct pid *p = get_pid(j) ; + for (j = 0; get_pid(j) != NULL; j++) { + const struct pid *p = get_pid(j); - for (i=0, ep=ecu_info; imode1_data) || - DATA_VALID(p, ep->mode2_data)) { + DATA_VALID(p, ep->mode2_data)) { printf("%-30.30s ", p->desc); if (DATA_VALID(p, ep->mode1_data)) { p->cust_snprintf(buf, sizeof(buf), english, p, - ep->mode1_data, 2); + ep->mode1_data, 2); } else { snprintf(buf, sizeof(buf), "-----"); } @@ -192,7 +186,7 @@ print_current_data(bool english) { if (DATA_VALID(p, ep->mode2_data)) { p->cust_snprintf(buf, sizeof(buf), english, p, - ep->mode2_data, 3); + ep->mode2_data, 3); } else { snprintf(buf, sizeof(buf), "-----"); } @@ -213,7 +207,7 @@ log_response(int ecu, response *r) { } printf("%d: ", ecu); - diag_data_dump(global_logfp, r->data,r->len); + diag_data_dump(global_logfp, r->data, r->len); fprintf(global_logfp, "\n"); } @@ -229,18 +223,18 @@ log_current_data(void) { log_timestamp("D"); fprintf(global_logfp, "MODE 1 DATA\n"); - for (i=0, ep=ecu_info; imode1_data; - r < &ep->mode1_data[ARRAY_SIZE(ep->mode1_data)]; r++) { - log_response((int)i, r); + for (i = 0, ep = ecu_info; i < ecu_count; i++, ep++) { + for (r = ep->mode1_data; r < &ep->mode1_data[ARRAY_SIZE(ep->mode1_data)]; + r++) { + log_response((int)i, r); } } log_timestamp("D"); fprintf(global_logfp, "MODE 2 DATA\n"); - for (i=0, ep=ecu_info; imode2_data; - r < &ep->mode2_data[ARRAY_SIZE(ep->mode2_data)]; r++) { + for (i = 0, ep = ecu_info; i < ecu_count; i++, ep++) { + for (r = ep->mode2_data; r < &ep->mode2_data[ARRAY_SIZE(ep->mode2_data)]; + r++) { log_response((int)i, r); } } @@ -282,9 +276,9 @@ cmd_monitor(int argc, char **argv) { while (1) { rv = do_j1979_getdata(1); /* Key pressed */ - if (rv == 1 || rv<0) { - //enter was pressed to interrupt, - //or there was an error. + if (rv == 1 || rv < 0) { + // enter was pressed to interrupt, + // or there was an error. break; } /* print the data */ @@ -299,11 +293,12 @@ cmd_monitor(int argc, char **argv) { return CMD_OK; } -// scan : use existing L3 J1979 connection, or establish a new one by trying all known protos. +// scan : use existing L3 J1979 connection, or establish a new one by trying all known +// protos. static int cmd_scan(UNUSED(int argc), UNUSED(char **argv)) { - int rv=DIAG_ERR_GENERAL; + int rv = DIAG_ERR_GENERAL; if (argc > 1) { return CMD_USAGE; } @@ -314,11 +309,13 @@ cmd_scan(UNUSED(int argc), UNUSED(char **argv)) { } if (global_state == STATE_L3ADDED) { if (global_l3_conn != NULL) { - if (strcmp(global_l3_conn->d_l3_proto->proto_name, "SAEJ1979") ==0) { + if (strcmp(global_l3_conn->d_l3_proto->proto_name, "SAEJ1979") == + 0) { printf("Re-using active L3 connection.\n"); - rv=0; + rv = 0; } else { - printf("L3 connection must be SAEJ1979 ! Try disconnecting and running scan again.\n"); + printf("L3 connection must be SAEJ1979 ! Try " + "disconnecting and running scan again.\n"); return CMD_FAILED; } } else { @@ -326,7 +323,8 @@ cmd_scan(UNUSED(int argc), UNUSED(char **argv)) { return CMD_FAILED; } } else if (global_state >= STATE_CONNECTED) { - printf("Already connected, please disconnect first, or manually add SAEJ1979 L3 layer.\n"); + printf("Already connected, please disconnect first, or manually add " + "SAEJ1979 L3 layer.\n"); return CMD_FAILED; } else { rv = ecu_connect(); @@ -354,8 +352,6 @@ cmd_scan(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - - static int cmd_cleardtc(UNUSED(int argc), UNUSED(char **argv)) { char *input; @@ -365,13 +361,15 @@ cmd_cleardtc(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - input = basic_get_input("Are you sure you wish to clear the Diagnostic " - "Trouble Codes (y/n) ? ", stdin); + input = basic_get_input( + "Are you sure you wish to clear the Diagnostic " + "Trouble Codes (y/n) ? ", + stdin); if (!input) { return CMD_OK; } - if ((strcasecmp(input, "yes") == 0) || (strcasecmp(input, "y")==0)) { + if ((strcasecmp(input, "yes") == 0) || (strcasecmp(input, "y") == 0)) { if (diag_cleardtc() == 0) { printf("Done\n"); } else { @@ -385,8 +383,6 @@ cmd_cleardtc(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - - static int cmd_ecus(UNUSED(int argc), UNUSED(char **argv)) { ecu_data *ep; @@ -399,7 +395,7 @@ cmd_ecus(UNUSED(int argc), UNUSED(char **argv)) { printf("%d ECUs found\n", ecu_count); - for (i=0, ep=ecu_info; iecu_addr & 0xff); if (ep->supress) { printf("output supressed for monitor mode\n"); @@ -414,29 +410,27 @@ static void print_resp_info(UNUSED(int mode), response *data) { int i; - for (i=0; i<256; i++) { + for (i = 0; i < 256; i++) { if (data->type != TYPE_UNTESTED) { if (data->type == TYPE_GOOD) { - printf("0x%02X: ", i ); + printf("0x%02X: ", i); diag_data_dump(stdout, data->data, data->len); printf("\n"); } else { - printf("0x%02X: Failed 0x%X\n", - i, data->data[1]); + printf("0x%02X: Failed 0x%X\n", i, data->data[1]); } } data++; } } - static int cmd_dumpdata(UNUSED(int argc), UNUSED(char **argv)) { ecu_data *ep; int i; printf("Current Data\n"); - for (i=0, ep=ecu_info; ivalid) { printf("ECU 0x%02X:\n", ep->ecu_addr & 0xff); print_resp_info(1, ep->mode1_data); @@ -444,7 +438,7 @@ cmd_dumpdata(UNUSED(int argc), UNUSED(char **argv)) { } printf("Freezeframe Data\n"); - for (i=0,ep=ecu_info; ivalid) { printf("ECU 0x%02X:\n", ep->ecu_addr & 0xff); print_resp_info(2, ep->mode2_data); @@ -454,16 +448,13 @@ cmd_dumpdata(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - - - /*print_pidinfo() : print supported PIDs (0 to 0x60) */ static void print_pidinfo(int mode, uint8_t *pid_data) { - int i,j; /* j : # pid per line */ + int i, j; /* j : # pid per line */ printf(" Mode %d:", mode); - for (i=0, j=0; i<=0x60; i++) { + for (i = 0, j = 0; i <= 0x60; i++) { if (j == 8) { j = 0; } @@ -479,8 +470,8 @@ print_pidinfo(int mode, uint8_t *pid_data) { printf("\n"); } - -static int cmd_pids(UNUSED(int argc), UNUSED(char **argv)) { +static int +cmd_pids(UNUSED(int argc), UNUSED(char **argv)) { ecu_data *ep; int i; @@ -489,10 +480,10 @@ static int cmd_pids(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - for (i=0,ep=ecu_info; ivalid) { - printf("ECU %d address 0x%02X: Supported PIDs:\n", - i, ep->ecu_addr & 0xff); + printf("ECU %d address 0x%02X: Supported PIDs:\n", i, + ep->ecu_addr & 0xff); print_pidinfo(1, ep->mode1_info); print_pidinfo(2, ep->mode2_info); print_pidinfo(5, ep->mode5_info); @@ -507,18 +498,14 @@ static int cmd_pids(UNUSED(int argc), UNUSED(char **argv)) { } const struct cmd_tbl_entry scantool_cmd_table[] = { - { "scan", "scan", "Start SCAN process", cmd_scan, 0, NULL}, - { "monitor", "monitor [english/metric]", "Continuously monitor rpm etc", - cmd_monitor, 0, NULL}, - { "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}, - { "dumpdata", "dumpdata", "Show Mode1 Pid1/2 responses", - cmd_dumpdata, 0, NULL}, - { "pids", "pids", "Shows PIDs supported by ECU", - cmd_pids, 0, NULL}, - { NULL, NULL, NULL, NULL, 0, NULL} -}; - + {"scan", "scan", "Start SCAN process", cmd_scan, 0, NULL}, + {"monitor", "monitor [english/metric]", "Continuously monitor rpm etc", + cmd_monitor, 0, NULL}, + {"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}, + {"dumpdata", "dumpdata", "Show Mode1 Pid1/2 responses", cmd_dumpdata, 0, NULL}, + {"pids", "pids", "Shows PIDs supported by ECU", cmd_pids, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL}}; diff --git a/scantool/scantool_set.c b/scantool/scantool_set.c index 26cc10ef..507a52d0 100644 --- a/scantool/scantool_set.c +++ b/scantool/scantool_set.c @@ -30,7 +30,7 @@ #include #include "diag.h" -#include "diag_cfg.h" //for cfgi +#include "diag_cfg.h" //for cfgi #include "diag_l0.h" #include "diag_l1.h" #include "diag_l2.h" @@ -45,43 +45,45 @@ struct globcfg global_cfg; struct diag_l0_device *global_dl0d; - /* * XXX All commands should probably have optional "init" hooks. */ -int set_init(void) { +int +set_init(void) { /* Reset parameters to defaults. */ - global_cfg.speed = 10400; /* Comms speed; ECUs will probably send at 10416 bps (96us per bit) */ + global_cfg.speed = 10400; /* Comms speed; ECUs will probably send at 10416 bps + (96us per bit) */ - global_cfg.src = 0xf1; /* Our tester ID */ - global_cfg.addrtype = 1; /* Use functional addressing */ - global_cfg.tgt = 0x33; /* Dest ECU address */ + global_cfg.src = 0xf1; /* Our tester ID */ + global_cfg.addrtype = 1; /* Use functional addressing */ + global_cfg.tgt = 0x33; /* Dest ECU address */ - global_cfg.L1proto = DIAG_L1_ISO9141; /* L1 protocol type */ + global_cfg.L1proto = DIAG_L1_ISO9141; /* L1 protocol type */ global_cfg.L2idx = 0; - global_cfg.L2proto = l2proto_list[0]->diag_l2_protocol; /* cannot guarantee 9141 was compiled... DIAG_L2_PROT_ISO9141; */ + global_cfg.L2proto = l2proto_list[0]->diag_l2_protocol; /* cannot guarantee 9141 + was compiled... + DIAG_L2_PROT_ISO9141; */ - global_cfg.initmode = DIAG_L2_TYPE_FASTINIT ; + global_cfg.initmode = DIAG_L2_TYPE_FASTINIT; - global_cfg.units = 0; /* English (1), or Metric (0) */ + global_cfg.units = 0; /* English (1), or Metric (0) */ - global_cfg.l0name = l0dev_list[0]->shortname; /* Default H/w interface to use */ + global_cfg.l0name = l0dev_list[0]->shortname; /* Default H/w interface to use */ - printf( "%s: Interface set to default: %s\n", progname, global_cfg.l0name); + printf("%s: Interface set to default: %s\n", progname, global_cfg.l0name); - global_dl0d=NULL; + global_dl0d = NULL; return 0; } -void set_close(void) { +void +set_close(void) { return; } - - /* SET sub menu */ static int cmd_set_custom(int argc, char **argv); static int cmd_set_help(int argc, char **argv); @@ -97,70 +99,65 @@ static int cmd_set_display(int argc, char **argv); static int cmd_set_interface(int argc, char **argv); const struct cmd_tbl_entry set_cmd_table[] = { - { "help", "help [command]", "Gives help for a command", - cmd_set_help, 0, NULL}, - { "?", "help [command]", "Gives help for a command", - cmd_set_help, FLAG_HIDDEN, NULL}, + {"help", "help [command]", "Gives help for a command", cmd_set_help, 0, NULL}, + {"?", "help [command]", "Gives help for a command", cmd_set_help, FLAG_HIDDEN, + NULL}, - { "interface", "interface [NAME]", "Interface to use. Use set interface ? to get a list of names", - cmd_set_interface, 0, NULL}, + {"interface", "interface [NAME]", + "Interface to use. Use set interface ? to get a list of names", cmd_set_interface, + 0, NULL}, - { "display", "display [english/metric]", "English or metric display", - cmd_set_display, 0, NULL}, + {"display", "display [english/metric]", "English or metric display", + cmd_set_display, 0, NULL}, - { "speed", "speed [speed]", "ECU communications speed", - cmd_set_speed, 0, NULL}, - { "testerid", "testerid [testerid]", "Source ID/address", - cmd_set_testerid, 0, NULL}, - { "destaddr", "destaddr [destaddr]","Destination ID/address", - cmd_set_destaddr, 0, NULL}, + {"speed", "speed [speed]", "ECU communications speed", cmd_set_speed, 0, NULL}, + {"testerid", "testerid [testerid]", "Source ID/address", cmd_set_testerid, 0, + NULL}, + {"destaddr", "destaddr [destaddr]", "Destination ID/address", cmd_set_destaddr, 0, + NULL}, - { "addrtype", "addrtype [func/phys]", "Address type, physical or functional.", - cmd_set_addrtype, 0, NULL}, + {"addrtype", "addrtype [func/phys]", "Address type, physical or functional.", + cmd_set_addrtype, 0, NULL}, - { "l1protocol", "l1protocol [protocolname]", "Hardware (L1) protocol to use. Use 'set l1protocol ?' to show valid choices.", - cmd_set_l1protocol, 0, NULL}, + {"l1protocol", "l1protocol [protocolname]", + "Hardware (L1) protocol to use. Use 'set l1protocol ?' to show valid choices.", + cmd_set_l1protocol, 0, NULL}, - { "l2protocol", "l2protocol [protocolname]", "Software (L2) protocol to use. Use 'set l2protocol ?' to show valid choices.", - cmd_set_l2protocol, 0, NULL}, + {"l2protocol", "l2protocol [protocolname]", + "Software (L2) protocol to use. Use 'set l2protocol ?' to show valid choices.", + cmd_set_l2protocol, 0, NULL}, - { "initmode", "initmode [modename]", "Bus initialisation mode to use. Use 'set initmode ?' to show valid choices.", - cmd_set_initmode, 0, NULL}, + {"initmode", "initmode [modename]", + "Bus initialisation mode to use. Use 'set initmode ?' to show valid choices.", + cmd_set_initmode, 0, NULL}, - { "show", "show", "Shows all settable values, including L0-specific items", - cmd_set_show, 0, NULL}, + {"show", "show", "Shows all settable values, including L0-specific items", + cmd_set_show, 0, NULL}, - { "up", "up", "Return to previous menu level", - cmd_up, 0, NULL}, - { "quit","quit", "Exit program", - cmd_exit, FLAG_HIDDEN, NULL}, - { "exit", "exit", "Exit program", - cmd_exit, 0, NULL}, - { "", "", "", - cmd_set_custom, FLAG_CUSTOM | FLAG_HIDDEN, NULL}, + {"up", "up", "Return to previous menu level", cmd_up, 0, NULL}, + {"quit", "quit", "Exit program", cmd_exit, FLAG_HIDDEN, NULL}, + {"exit", "exit", "Exit program", cmd_exit, 0, NULL}, + {"", "", "", cmd_set_custom, FLAG_CUSTOM | FLAG_HIDDEN, NULL}, - { NULL, NULL, NULL, NULL, 0, NULL} -}; + {NULL, NULL, NULL, NULL, 0, NULL}}; -const char *const l1_names[] = { //these MUST be in the same order as they are listed in diag_l1.h !! - "ISO9141", "ISO14230", - "J1850-VPW", "J1850-PWM", "CAN", "", "", "RAW", NULL -}; +const char *const l1_names[] = { // these MUST be in the same order as they are listed in + // diag_l1.h !! + "ISO9141", "ISO14230", "J1850-VPW", "J1850-PWM", "CAN", "", "", "RAW", NULL}; -//These MUST match the DIAG_L2_TYPE_* flags in diag_l2.h so that +// These MUST match the DIAG_L2_TYPE_* flags in diag_l2.h so that // l2_initmodes[DIAG_L2_TYPE_XX] == "XX" !! -const char *const l2_initmodes[] = { - "5BAUD", "FAST", "CARB", NULL -}; +const char *const l2_initmodes[] = {"5BAUD", "FAST", "CARB", NULL}; // handle dynamic options (L0-specific). // argv[0] is the config shortname, etc. // if argv[0] is '?' (special case), this prints available subcommands. -static int cmd_set_custom(int argc, char **argv) { +static int +cmd_set_custom(int argc, char **argv) { struct cfgi *cfgp; char *setstr; - bool helping=0; - bool show_current=0; + bool helping = 0; + bool show_current = 0; int newval; if (!global_dl0d) { @@ -168,12 +165,14 @@ static int cmd_set_custom(int argc, char **argv) { if (strcmp(argv[0], "?") == 0) { return CMD_OK; } - printf("No such item !\nAdditional items may be available after setting the interface type.\nUse \"set interface NAME\" to set the interface type.\n"); + printf("No such item !\nAdditional items may be available after setting " + "the interface type.\nUse \"set interface NAME\" to set the " + "interface type.\n"); return CMD_FAILED; } if (strcmp(argv[0], "?") == 0) { - //list available custom commands for the current L0. + // list available custom commands for the current L0. LL_FOREACH(diag_l0_getcfg(global_dl0d), cfgp) { printf("\t%s\n", cfgp->shortname); } @@ -186,7 +185,7 @@ static int cmd_set_custom(int argc, char **argv) { } } else { // no args: display current settings - show_current = 1; + show_current = 1; } /* find the config item */ @@ -214,27 +213,27 @@ static int cmd_set_custom(int argc, char **argv) { if (cfgp->numopts > 0) { int i; printf("Available options:\n"); - for (i=0; i < cfgp->numopts; i++) { + for (i = 0; i < cfgp->numopts; i++) { printf("\t\t%s\n", cfgp->opt[i]); } } return CMD_OK; } -/* TODO : move this to diag_cfg.* if it works */ + /* TODO : move this to diag_cfg.* if it works */ newval = htoi(argv[1]); switch (cfgp->type) { case CFGT_STR: diag_cfg_setstr(cfgp, argv[1]); break; case CFGT_U8: - diag_cfg_setu8(cfgp, (uint8_t) newval); + diag_cfg_setu8(cfgp, (uint8_t)newval); break; case CFGT_INT: diag_cfg_setint(cfgp, newval); break; case CFGT_BOOL: - diag_cfg_setbool(cfgp, (bool) newval); + diag_cfg_setbool(cfgp, (bool)newval); break; default: return CMD_FAILED; @@ -248,16 +247,17 @@ static int cmd_set_custom(int argc, char **argv) { static int cmd_set_show(UNUSED(int argc), UNUSED(char **argv)) { - /* Show stuff; calling the cmd_set_*() functions with argc=0 displays the current setting. */ - cmd_set_interface(0,NULL); + /* Show stuff; calling the cmd_set_*() functions with argc=0 displays the current + * setting. */ + cmd_set_interface(0, NULL); cmd_set_speed(0, NULL); - cmd_set_display(0,NULL); - cmd_set_testerid(0,NULL); - cmd_set_addrtype(0,NULL); - cmd_set_destaddr(0,NULL); - cmd_set_l1protocol(0,NULL); - cmd_set_l2protocol(0,NULL); - cmd_set_initmode(0,NULL); + cmd_set_display(0, NULL); + cmd_set_testerid(0, NULL); + cmd_set_addrtype(0, NULL); + cmd_set_destaddr(0, NULL); + cmd_set_l1protocol(0, NULL); + cmd_set_l2protocol(0, NULL); + cmd_set_initmode(0, NULL); /* Parse L0-specific config items */ if (global_dl0d) { @@ -269,7 +269,7 @@ cmd_set_show(UNUSED(int argc), UNUSED(char **argv)) { continue; } - printf("\t%s=%s\n",cfgp->shortname, cs); + printf("\t%s=%s\n", cfgp->shortname, cs); free(cs); } } @@ -277,13 +277,12 @@ cmd_set_show(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - -static int cmd_set_interface(int argc, char **argv) { +static int +cmd_set_interface(int argc, char **argv) { const struct diag_l0 *iter; if (argc <= 1) { - printf("interface: using %s\n", - global_cfg.l0name); + printf("interface: using %s\n", global_cfg.l0name); return CMD_OK; } if (argc > 2) { @@ -303,16 +302,16 @@ static int cmd_set_interface(int argc, char **argv) { helping = 1; printf("Valid interface names (not case sensitive): \n\t"); } - for (i=0; l0dev_list[i]; i++) { + for (i = 0; l0dev_list[i]; i++) { iter = l0dev_list[i]; - //loop through l0 interface names, either printing or comparing to argv[1] + // loop through l0 interface names, either printing or comparing to argv[1] if (helping) { printf("%s ", iter->shortname); } else if (strcasecmp(argv[1], iter->shortname) == 0) { global_cfg.l0name = iter->shortname; found = 1; break; // no use in continuing - } + } } if (helping) { @@ -354,7 +353,7 @@ cmd_set_display(int argc, char **argv) { return CMD_USAGE; } } else { - printf("display: %s units\n", global_cfg.units?"english":"metric"); + printf("display: %s units\n", global_cfg.units ? "english" : "metric"); } return CMD_OK; @@ -382,13 +381,13 @@ cmd_set_testerid(int argc, char **argv) { return CMD_USAGE; } tmp = htoi(argv[1]); - if ( (tmp < 0) || (tmp > 0xff)) { + if ((tmp < 0) || (tmp > 0xff)) { printf("testerid: must be between 0 and 0xff\n"); return CMD_FAILED; } - global_cfg.src = (uint8_t) tmp; + global_cfg.src = (uint8_t)tmp; } - printf("testerid: using 0x%02X\n", (unsigned) global_cfg.src); + printf("testerid: using 0x%02X\n", (unsigned)global_cfg.src); return CMD_OK; } @@ -401,14 +400,13 @@ cmd_set_destaddr(int argc, char **argv) { return CMD_USAGE; } tmp = htoi(argv[1]); - if ( (tmp < 0) || (tmp > 0xff)) { + if ((tmp < 0) || (tmp > 0xff)) { printf("destaddr: must be between 0 and 0xff\n"); return CMD_FAILED; } - global_cfg.tgt = (uint8_t) tmp; + global_cfg.tgt = (uint8_t)tmp; } - printf("destaddr: using 0x%02X\n", - (unsigned) global_cfg.tgt); + printf("destaddr: using 0x%02X\n", (unsigned)global_cfg.tgt); return CMD_OK; } @@ -425,24 +423,25 @@ cmd_set_addrtype(int argc, char **argv) { } } else { printf("addrtype: %s addressing\n", - global_cfg.addrtype ? "functional" : "physical"); + global_cfg.addrtype ? "functional" : "physical"); } return CMD_OK; } -static int cmd_set_l2protocol(int argc, char **argv) { +static int +cmd_set_l2protocol(int argc, char **argv) { if (argc > 1) { int i, helping = 0, found = 0; if (strcmp(argv[1], "?") == 0) { helping = 1; printf("L2 protocol: valid names are "); } - for (i=0; l2proto_list[i] != NULL; i++) { - const struct diag_l2_proto *d2p=l2proto_list[i]; + for (i = 0; l2proto_list[i] != NULL; i++) { + const struct diag_l2_proto *d2p = l2proto_list[i]; if (helping) { - printf("%s ", d2p->shortname); - continue; + printf("%s ", d2p->shortname); + continue; } if (strcasecmp(argv[1], d2p->shortname) == 0) { found = 1; @@ -455,63 +454,66 @@ static int cmd_set_l2protocol(int argc, char **argv) { printf("\n"); return CMD_USAGE; } - if (! found) { + if (!found) { printf("l2protocol: invalid protocol %s\n", argv[1]); - printf("l2protocol: use \"set l2protocol ?\" to see list of protocols\n"); + printf("l2protocol: use \"set l2protocol ?\" to see list of " + "protocols\n"); } } else { printf("l2protocol: Layer 2 protocol to use %s\n", - l2proto_list[global_cfg.L2idx]->shortname); + l2proto_list[global_cfg.L2idx]->shortname); } return CMD_OK; } -static int cmd_set_l1protocol(int argc, char **argv) { +static int +cmd_set_l1protocol(int argc, char **argv) { if (argc > 1) { int i, helping = 0, found = 0; if (strcmp(argv[1], "?") == 0) { helping = 1; printf("L1 protocol: valid names are "); } - for (i=0; l1_names[i] != NULL; i++) { + for (i = 0; l1_names[i] != NULL; i++) { if (helping && *l1_names[i]) { printf("%s ", l1_names[i]); } else if (strcasecmp(argv[1], l1_names[i]) == 0) { global_cfg.L1proto = 1 << i; found = 1; - } + } } if (helping) { printf("\n"); return CMD_USAGE; } - if (! found) { + if (!found) { printf("L1protocol: invalid protocol %s\n", argv[1]); - printf("l1protocol: use \"set l1protocol ?\" to see list of protocols\n"); + printf("l1protocol: use \"set l1protocol ?\" to see list of " + "protocols\n"); } return CMD_OK; } int offset; - for (offset=0; offset < 8; offset++) { + for (offset = 0; offset < 8; offset++) { if (global_cfg.L1proto == (1 << offset)) { break; } } - printf("l1protocol: Layer 1 (H/W) protocol to use %s\n", - l1_names[offset]); + printf("l1protocol: Layer 1 (H/W) protocol to use %s\n", l1_names[offset]); return CMD_OK; } -static int cmd_set_initmode(int argc, char **argv) { +static int +cmd_set_initmode(int argc, char **argv) { if (argc > 1) { int i, helping = 0, found = 0; if (strcmp(argv[1], "?") == 0) { helping = 1; } - for (i=0; l2_initmodes[i] != NULL; i++) { + for (i = 0; l2_initmodes[i] != NULL; i++) { if (helping) { printf("%s ", l2_initmodes[i]); } else { @@ -525,15 +527,16 @@ static int cmd_set_initmode(int argc, char **argv) { printf("\n"); return CMD_USAGE; } - if (! found) { + if (!found) { printf("initmode: invalid mode %s\n", argv[1]); - printf("initmode: use \"set initmode ?\" to see list of initmodes\n"); + printf("initmode: use \"set initmode ?\" to see list of " + "initmodes\n"); } return CMD_OK; } printf("initmode: Initmode to use with above protocol is %s\n", - l2_initmodes[global_cfg.initmode]); + l2_initmodes[global_cfg.initmode]); return CMD_OK; } diff --git a/scantool/scantool_test.c b/scantool/scantool_test.c index 30b89acd..d3cef403 100644 --- a/scantool/scantool_test.c +++ b/scantool/scantool_test.c @@ -26,7 +26,7 @@ * CLI routines - test subcommand */ -#include "diag.h" /* operating specific includes */ +#include "diag.h" /* operating specific includes */ #include "diag_l3.h" /* operating specific includes */ #include "scantool.h" @@ -41,38 +41,27 @@ static int cmd_test_ncms(int argc, char **argv); static int cmd_test_readiness(int argc, char **argv); const struct cmd_tbl_entry test_cmd_table[] = { - { "help", "help [command]", "Gives help for a command", - cmd_test_help, 0, NULL}, - { "?", "? [command]", "Gives help for a command", - cmd_test_help, FLAG_HIDDEN, NULL}, - { "rvi", "rvi", "Send request vehicle info commands to the ECU", - cmd_test_rvi, 0, NULL}, - { "cms", "cms", - "Get test results for continuously monitored systems", - cmd_test_cms, 0, NULL}, - { "ncms", "ncms", - "Get test results for non-continuously monitored systems", - cmd_test_ncms, 0, NULL}, - { "readiness", "readiness", - "Do readiness tests", - cmd_test_readiness, 0, NULL}, - - { "up", "up", "Return to previous menu level", - cmd_up, 0, NULL}, - { "quit","quit", "Exit program", - cmd_exit, FLAG_HIDDEN, NULL}, - { "exit", "exit", "Exit program", - cmd_exit, 0, NULL}, - - { NULL, NULL, NULL, NULL, 0, NULL} -}; + {"help", "help [command]", "Gives help for a command", cmd_test_help, 0, NULL}, + {"?", "? [command]", "Gives help for a command", cmd_test_help, FLAG_HIDDEN, NULL}, + {"rvi", "rvi", "Send request vehicle info commands to the ECU", cmd_test_rvi, 0, + NULL}, + {"cms", "cms", "Get test results for continuously monitored systems", cmd_test_cms, + 0, NULL}, + {"ncms", "ncms", "Get test results for non-continuously monitored systems", + cmd_test_ncms, 0, NULL}, + {"readiness", "readiness", "Do readiness tests", cmd_test_readiness, 0, NULL}, + + {"up", "up", "Return to previous menu level", cmd_up, 0, NULL}, + {"quit", "quit", "Exit program", cmd_exit, FLAG_HIDDEN, NULL}, + {"exit", "exit", "Exit program", cmd_exit, 0, NULL}, + + {NULL, NULL, NULL, NULL, 0, NULL}}; static int cmd_test_help(int argc, char **argv) { return help_common(argc, argv, test_cmd_table); } - /* * Guts of routine to ask for VIN/CID/CVN * return data length (excluding 0x00 termination) if ok (data written to *obuf) @@ -81,10 +70,11 @@ static unsigned get_vit_info(struct diag_l3_conn *d_conn, uint8_t itype, uint8_t *obuf, unsigned buflen) { struct diag_msg *msg, *msgcur; int rv; - unsigned offset ; + unsigned offset; /* Now request the VIN */ - rv = l3_do_j1979_rqst(d_conn, 9, itype, 0, 0, 0, 0, 0, (void *)&_RQST_HANDLE_NORMAL); + rv = l3_do_j1979_rqst(d_conn, 9, itype, 0, 0, 0, 0, 0, + (void *)&_RQST_HANDLE_NORMAL); if (rv < 0) { printf("Failed to get infotype 0x%X info\n", itype); return 0; @@ -100,7 +90,7 @@ get_vit_info(struct diag_l3_conn *d_conn, uint8_t itype, uint8_t *obuf, unsigned LL_FOREACH(msg, msgcur) { memcpy(&obuf[offset], &msgcur->data[3], 4); offset += 4; - if (offset >= buflen ) { + if (offset >= buflen) { offset = buflen - 1; printf("Clipped Mode 9 response\n"); break; @@ -110,7 +100,6 @@ get_vit_info(struct diag_l3_conn *d_conn, uint8_t itype, uint8_t *obuf, unsigned return offset; } - /* Request Vehicle Info */ static int @@ -127,22 +116,21 @@ cmd_test_rvi(UNUSED(int argc), UNUSED(char **argv)) { ecu_data *ep; unsigned i; bool merged_mode9_info[0x100]; - #define MODE9_INFO_MAXLEN 0x100 +#define MODE9_INFO_MAXLEN 0x100 uint8_t infostring[MODE9_INFO_MAXLEN]; - - /* merge all infotypes supported by all ECUs */ + /* merge all infotypes supported by all ECUs */ memset(merged_mode9_info, 0, sizeof(merged_mode9_info)); - for (i=0, ep=ecu_info; imode9_info);j++) { - merged_mode9_info[j] |= ep->mode9_info[j] ; + for (j = 0; j < sizeof(ep->mode9_info); j++) { + merged_mode9_info[j] |= ep->mode9_info[j]; } } if (merged_mode9_info[2]) { if (get_vit_info(d_conn, 2, infostring, MODE9_INFO_MAXLEN) > 3) { - printf("VIN: %s\n", (char *) &infostring[3]); //skip padding ! + printf("VIN: %s\n", (char *)&infostring[3]); // skip padding ! } } else { printf("ECU doesn't support VIN request\n"); @@ -150,7 +138,7 @@ cmd_test_rvi(UNUSED(int argc), UNUSED(char **argv)) { if (merged_mode9_info[4]) { if (get_vit_info(d_conn, 4, infostring, MODE9_INFO_MAXLEN)) { - printf("Calibration ID: %s\n", (char *) infostring); + printf("Calibration ID: %s\n", (char *)infostring); } } else { printf("ECU doesn't support Calibration ID request\n"); @@ -171,9 +159,6 @@ cmd_test_rvi(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - - - static int cmd_test_cms(UNUSED(int argc), UNUSED(char **argv)) { if (global_state < STATE_SCANDONE) { @@ -184,7 +169,6 @@ cmd_test_cms(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - static int cmd_test_ncms(UNUSED(int argc), UNUSED(char **argv)) { if (global_state < STATE_SCANDONE) { @@ -195,7 +179,6 @@ cmd_test_ncms(UNUSED(int argc), UNUSED(char **argv)) { return CMD_OK; } - static int cmd_test_readiness(UNUSED(int argc), UNUSED(char **argv)) { int rv; @@ -204,20 +187,18 @@ cmd_test_readiness(UNUSED(int argc), UNUSED(char **argv)) { unsigned int i; const char *text; - const char *test_names[] = { - "Misfire Monitoring", - "Fuel System Monitoring", - "Comprehensive Component Monitoring", - NULL, - "Catalyst Monitoring", - "Heated Catalyst Monitoring", - "Evaporative System Monitoring", - "Secondary Air System Monitoring", - "A/C System Refrigerant Monitoring", - "Oxygen Sensor Monitoring", - "Oxygen Sensor Heater Monitor", - "EGR System Monitoring" - }; + const char *test_names[] = {"Misfire Monitoring", + "Fuel System Monitoring", + "Comprehensive Component Monitoring", + NULL, + "Catalyst Monitoring", + "Heated Catalyst Monitoring", + "Evaporative System Monitoring", + "Secondary Air System Monitoring", + "A/C System Refrigerant Monitoring", + "Oxygen Sensor Monitoring", + "Oxygen Sensor Heater Monitor", + "EGR System Monitoring"}; d_conn = global_l3_conn; @@ -227,9 +208,8 @@ cmd_test_readiness(UNUSED(int argc), UNUSED(char **argv)) { } /* Do Mode 1 Pid 1 request */ - rv = l3_do_j1979_rqst(d_conn, 1, 1, 0x00, - 0x00, 0x00, 0x00, 0x00, - (void *)&_RQST_HANDLE_READINESS); + rv = l3_do_j1979_rqst(d_conn, 1, 1, 0x00, 0x00, 0x00, 0x00, 0x00, + (void *)&_RQST_HANDLE_READINESS); if ((rv < 0) || (find_ecu_msg(0, 0x41) == NULL)) { printf("Mode 1 PID 1 request failed\n"); @@ -237,29 +217,30 @@ cmd_test_readiness(UNUSED(int argc), UNUSED(char **argv)) { } /* And process results */ - for (i=0, ep=ecu_info; imode1_data[1].type == TYPE_GOOD) { int supported, value; - for (i=0; i<12; i++) { + for (i = 0; i < 12; i++) { text = test_names[i]; if (text == NULL) { continue; } - if (i<4) { - supported = (ep->mode1_data[1].data[3]>>i)&1; - value = (ep->mode1_data[1].data[3]>>(i+4))&1; + if (i < 4) { + supported = (ep->mode1_data[1].data[3] >> i) & 1; + value = (ep->mode1_data[1].data[3] >> (i + 4)) & 1; } else { - supported = (ep->mode1_data[1].data[4]>>(i-4))&1; - value = (ep->mode1_data[1].data[5]>>(i-4))&1; + supported = + (ep->mode1_data[1].data[4] >> (i - 4)) & 1; + value = (ep->mode1_data[1].data[5] >> (i - 4)) & 1; } if (ecu_count > 1) { printf("ECU %d: ", i); } printf("%s: ", text); if (supported) { - printf("%sComplete\n", value?"":"NOT "); + printf("%sComplete\n", value ? "" : "NOT "); } else { printf("Not Supported\n"); } diff --git a/scantool/scantool_vag.c b/scantool/scantool_vag.c index a96a220b..7d7fc986 100644 --- a/scantool/scantool_vag.c +++ b/scantool/scantool_vag.c @@ -34,25 +34,16 @@ #include "scantool.h" #include "scantool_cli.h" - static int cmd_vag_help(int argc, char **argv); const struct cmd_tbl_entry vag_cmd_table[] = { - { "help", "help [command]", "Gives help for a command", - cmd_vag_help, 0, NULL}, - { "?", "? [command]", "Gives help for a command", - cmd_vag_help, 0, NULL}, - + {"help", "help [command]", "Gives help for a command", cmd_vag_help, 0, NULL}, + {"?", "? [command]", "Gives help for a command", cmd_vag_help, 0, NULL}, - { "up", "up", "Return to previous menu level", - cmd_up, 0, NULL}, - { "quit","quit", "Exit program", - cmd_exit, FLAG_HIDDEN, NULL}, - { "exit", "exit", "Exit program", - cmd_exit, 0, NULL}, - - { NULL, NULL, NULL, NULL, 0, NULL} -}; + {"up", "up", "Return to previous menu level", cmd_up, 0, NULL}, + {"quit", "quit", "Exit program", cmd_exit, FLAG_HIDDEN, NULL}, + {"exit", "exit", "Exit program", cmd_exit, 0, NULL}, + {NULL, NULL, NULL, NULL, 0, NULL}}; /* * Table of english descriptions of the VW ECU addresses @@ -60,15 +51,12 @@ const struct cmd_tbl_entry vag_cmd_table[] = { struct vw_id_info { const int id; const char *command; -} ; +}; const struct vw_id_info vw_ids[] = { - {DIAG_VAG_ECU_ENGINE, "Engine" }, - {DIAG_VAG_ECU_GEARBOX, "Gearbox" }, - {DIAG_VAG_ECU_ABS, "ABS" }, - {DIAG_VAG_ECU_AIRBAGS, "Airbag" }, - {DIAG_VAG_ECU_LOCKS, "Locking" }, - {0, NULL}, + {DIAG_VAG_ECU_ENGINE, "Engine"}, {DIAG_VAG_ECU_GEARBOX, "Gearbox"}, + {DIAG_VAG_ECU_ABS, "ABS"}, {DIAG_VAG_ECU_AIRBAGS, "Airbag"}, + {DIAG_VAG_ECU_LOCKS, "Locking"}, {0, NULL}, }; static int diff --git a/scantool/utlist.h b/scantool/utlist.h index 83cd730f..326a5652 100644 --- a/scantool/utlist.h +++ b/scantool/utlist.h @@ -70,298 +70,339 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. As decltype is only available in newer compilers (VS2010 or gcc 4.3+ when compiling c++ code), this code uses whatever method is needed or, for VS2008 where neither is available, uses casting workarounds. */ -#ifdef _MSC_VER /* MS compiler */ -#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ -#define LDECLTYPE(x) decltype(x) -#else /* VS2008 or older (or VS2010 in C mode) */ -#define NO_DECLTYPE -#define LDECLTYPE(x) char* -#endif +#ifdef _MSC_VER /* MS compiler */ +# if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +# define LDECLTYPE(x) decltype(x) +# else /* VS2008 or older (or VS2010 in C mode) */ +# define NO_DECLTYPE +# define LDECLTYPE(x) char * +# endif #elif defined(__ICCARM__) -#define NO_DECLTYPE -#define LDECLTYPE(x) char* -#else /* GNU, Sun and other compilers */ -#define LDECLTYPE(x) __typeof(x) +# define NO_DECLTYPE +# define LDECLTYPE(x) char * +#else /* GNU, Sun and other compilers */ +# define LDECLTYPE(x) __typeof(x) #endif /* for VS2008 we use some workarounds to get around the lack of decltype, * namely, we always reassign our tmp variable to the list head if we need * to dereference its prev/next pointers, and save/restore the real head.*/ #ifdef NO_DECLTYPE -#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } -#define _NEXT(elt,list,next) ((char*)((list)->next)) -#define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } +# define _SV(elt, list) \ + _tmp = (char *)(list); \ + { \ + char **_alias = (char **)&(list); \ + *_alias = (elt); \ + } +# define _NEXT(elt, list, next) ((char *)((list)->next)) +# define _NEXTASGN(elt, list, to, next) \ + { \ + char **_alias = (char **)&((list)->next); \ + *_alias = (char *)(to); \ + } /* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */ -#define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } -#define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } -#define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } +# define _PREVASGN(elt, list, to, prev) \ + { \ + char **_alias = (char **)&((list)->prev); \ + *_alias = (char *)(to); \ + } +# define _RS(list) \ + { \ + char **_alias = (char **)&(list); \ + *_alias = _tmp; \ + } +# define _CASTASGN(a, b) \ + { \ + char **_alias = (char **)&(a); \ + *_alias = (char *)(b); \ + } #else -#define _SV(elt,list) -#define _NEXT(elt,list,next) ((elt)->next) -#define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to) +# define _SV(elt, list) +# define _NEXT(elt, list, next) ((elt)->next) +# define _NEXTASGN(elt, list, to, next) ((elt)->next) = (to) /* #define _PREV(elt,list,prev) ((elt)->prev) */ -#define _PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) -#define _RS(list) -#define _CASTASGN(a,b) (a)=(b) +# define _PREVASGN(elt, list, to, prev) ((elt)->prev) = (to) +# define _RS(list) +# define _CASTASGN(a, b) (a) = (b) #endif /****************************************************************************** * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * * Unwieldy variable names used here to avoid shadowing passed-in variables. * *****************************************************************************/ -#define LL_SORT(list, cmp) \ - LL_SORT2(list, cmp, next) - -#define LL_SORT2(list, cmp, next) \ -do { \ - LDECLTYPE(list) _ls_p; \ - LDECLTYPE(list) _ls_q; \ - LDECLTYPE(list) _ls_e; \ - LDECLTYPE(list) _ls_tail; \ - int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ - if (list) { \ - _ls_insize = 1; \ - _ls_looping = 1; \ - while (_ls_looping) { \ - _CASTASGN(_ls_p,list); \ - list = NULL; \ - _ls_tail = NULL; \ - _ls_nmerges = 0; \ - while (_ls_p) { \ - _ls_nmerges++; \ - _ls_q = _ls_p; \ - _ls_psize = 0; \ - for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ - _ls_psize++; \ - _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ - if (!_ls_q) break; \ - } \ - _ls_qsize = _ls_insize; \ - while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ - if (_ls_psize == 0) { \ - _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ - _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ - } else if (_ls_qsize == 0 || !_ls_q) { \ - _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ - _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ - } else if (cmp(_ls_p,_ls_q) <= 0) { \ - _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ - _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ - } else { \ - _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ - _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ - } \ - if (_ls_tail) { \ - _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ - } else { \ - _CASTASGN(list,_ls_e); \ - } \ - _ls_tail = _ls_e; \ - } \ - _ls_p = _ls_q; \ - } \ - if (_ls_tail) { \ - _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ - } \ - if (_ls_nmerges <= 1) { \ - _ls_looping=0; \ - } \ - _ls_insize *= 2; \ - } \ - } \ -} while (0) +#define LL_SORT(list, cmp) LL_SORT2(list, cmp, next) + +#define LL_SORT2(list, cmp, next) \ + do { \ + LDECLTYPE(list) _ls_p; \ + LDECLTYPE(list) _ls_q; \ + LDECLTYPE(list) _ls_e; \ + LDECLTYPE(list) _ls_tail; \ + int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ + if (list) { \ + _ls_insize = 1; \ + _ls_looping = 1; \ + while (_ls_looping) { \ + _CASTASGN(_ls_p, list); \ + list = NULL; \ + _ls_tail = NULL; \ + _ls_nmerges = 0; \ + while (_ls_p) { \ + _ls_nmerges++; \ + _ls_q = _ls_p; \ + _ls_psize = 0; \ + for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ + _ls_psize++; \ + _SV(_ls_q, list); \ + _ls_q = _NEXT(_ls_q, list, next); \ + _RS(list); \ + if (!_ls_q) \ + break; \ + } \ + _ls_qsize = _ls_insize; \ + while (_ls_psize > 0 || \ + (_ls_qsize > 0 && _ls_q)) { \ + if (_ls_psize == 0) { \ + _ls_e = _ls_q; \ + _SV(_ls_q, list); \ + _ls_q = _NEXT(_ls_q, list, next); \ + _RS(list); \ + _ls_qsize--; \ + } else if (_ls_qsize == 0 || !_ls_q) { \ + _ls_e = _ls_p; \ + _SV(_ls_p, list); \ + _ls_p = _NEXT(_ls_p, list, next); \ + _RS(list); \ + _ls_psize--; \ + } else if (cmp(_ls_p, _ls_q) <= 0) { \ + _ls_e = _ls_p; \ + _SV(_ls_p, list); \ + _ls_p = _NEXT(_ls_p, list, next); \ + _RS(list); \ + _ls_psize--; \ + } else { \ + _ls_e = _ls_q; \ + _SV(_ls_q, list); \ + _ls_q = _NEXT(_ls_q, list, next); \ + _RS(list); \ + _ls_qsize--; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail, list); \ + _NEXTASGN(_ls_tail, list, _ls_e, \ + next); \ + _RS(list); \ + } else { \ + _CASTASGN(list, _ls_e); \ + } \ + _ls_tail = _ls_e; \ + } \ + _ls_p = _ls_q; \ + } \ + if (_ls_tail) { \ + _SV(_ls_tail, list); \ + _NEXTASGN(_ls_tail, list, NULL, next); \ + _RS(list); \ + } \ + if (_ls_nmerges <= 1) { \ + _ls_looping = 0; \ + } \ + _ls_insize *= 2; \ + } \ + } \ + } while (0) /****************************************************************************** * singly linked list macros (non-circular) * *****************************************************************************/ -#define LL_PREPEND(head,add) \ - LL_PREPEND2(head,add,next) - -#define LL_PREPEND2(head,add,next) \ -do { \ - (add)->next = head; \ - head = add; \ -} while (0) - -#define LL_CONCAT(head1,head2) \ - LL_CONCAT2(head1,head2,next) - -#define LL_CONCAT2(head1,head2,next) \ -do { \ - LDECLTYPE(head1) _tmp; \ - if (head1) { \ - _tmp = head1; \ - while (_tmp->next) { _tmp = _tmp->next; } \ - _tmp->next=(head2); \ - } else { \ - (head1)=(head2); \ - } \ -} while (0) - -#define LL_APPEND(head,add) \ - LL_APPEND2(head,add,next) - -#define LL_APPEND2(head,add,next) \ -do { \ - LDECLTYPE(head) _tmp; \ - (add)->next=NULL; \ - if (head) { \ - _tmp = head; \ - while (_tmp->next) { _tmp = _tmp->next; } \ - _tmp->next=(add); \ - } else { \ - (head)=(add); \ - } \ -} while (0) - -#define LL_DELETE(head,del) \ - LL_DELETE2(head,del,next) - -#define LL_DELETE2(head,del,next) \ -do { \ - LDECLTYPE(head) _tmp; \ - if ((head) == (del)) { \ - (head)=(head)->next; \ - } else { \ - _tmp = head; \ - while (_tmp->next && (_tmp->next != (del))) { \ - _tmp = _tmp->next; \ - } \ - if (_tmp->next) { \ - _tmp->next = ((del)->next); \ - } \ - } \ -} while (0) +#define LL_PREPEND(head, add) LL_PREPEND2(head, add, next) + +#define LL_PREPEND2(head, add, next) \ + do { \ + (add)->next = head; \ + head = add; \ + } while (0) + +#define LL_CONCAT(head1, head2) LL_CONCAT2(head1, head2, next) + +#define LL_CONCAT2(head1, head2, next) \ + do { \ + LDECLTYPE(head1) _tmp; \ + if (head1) { \ + _tmp = head1; \ + while (_tmp->next) { \ + _tmp = _tmp->next; \ + } \ + _tmp->next = (head2); \ + } else { \ + (head1) = (head2); \ + } \ + } while (0) + +#define LL_APPEND(head, add) LL_APPEND2(head, add, next) + +#define LL_APPEND2(head, add, next) \ + do { \ + LDECLTYPE(head) _tmp; \ + (add)->next = NULL; \ + if (head) { \ + _tmp = head; \ + while (_tmp->next) { \ + _tmp = _tmp->next; \ + } \ + _tmp->next = (add); \ + } else { \ + (head) = (add); \ + } \ + } while (0) + +#define LL_DELETE(head, del) LL_DELETE2(head, del, next) + +#define LL_DELETE2(head, del, next) \ + do { \ + LDECLTYPE(head) _tmp; \ + if ((head) == (del)) { \ + (head) = (head)->next; \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (del))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = ((del)->next); \ + } \ + } \ + } while (0) /* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ -#define LL_APPEND_VS2008(head,add) \ - LL_APPEND2_VS2008(head,add,next) - -#define LL_APPEND2_VS2008(head,add,next) \ -do { \ - if (head) { \ - (add)->next = head; /* use add->next as a temp variable */ \ - while ((add)->next->next) { (add)->next = (add)->next->next; } \ - (add)->next->next=(add); \ - } else { \ - (head)=(add); \ - } \ - (add)->next=NULL; \ -} while (0) - -#define LL_DELETE_VS2008(head,del) \ - LL_DELETE2_VS2008(head,del,next) - -#define LL_DELETE2_VS2008(head,del,next) \ -do { \ - if ((head) == (del)) { \ - (head)=(head)->next; \ - } else { \ - char *_tmp = (char *)(head); \ - while ((head)->next && ((head)->next != (del))) { \ - head = (head)->next; \ - } \ - if ((head)->next) { \ - (head)->next = ((del)->next); \ - } \ - { \ - char **_head_alias = (char **)&(head); \ - *_head_alias = _tmp; \ - } \ - } \ -} while (0) +#define LL_APPEND_VS2008(head, add) LL_APPEND2_VS2008(head, add, next) + +#define LL_APPEND2_VS2008(head, add, next) \ + do { \ + if (head) { \ + (add)->next = head; /* use add->next as a temp variable */ \ + while ((add)->next->next) { \ + (add)->next = (add)->next->next; \ + } \ + (add)->next->next = (add); \ + } else { \ + (head) = (add); \ + } \ + (add)->next = NULL; \ + } while (0) + +#define LL_DELETE_VS2008(head, del) LL_DELETE2_VS2008(head, del, next) + +#define LL_DELETE2_VS2008(head, del, next) \ + do { \ + if ((head) == (del)) { \ + (head) = (head)->next; \ + } else { \ + char *_tmp = (char *)(head); \ + while ((head)->next && ((head)->next != (del))) { \ + head = (head)->next; \ + } \ + if ((head)->next) { \ + (head)->next = ((del)->next); \ + } \ + { \ + char **_head_alias = (char **)&(head); \ + *_head_alias = _tmp; \ + } \ + } \ + } while (0) #ifdef NO_DECLTYPE -#undef LL_APPEND -#define LL_APPEND LL_APPEND_VS2008 -#undef LL_DELETE -#define LL_DELETE LL_DELETE_VS2008 -#undef LL_DELETE2 -#define LL_DELETE2 LL_DELETE2_VS2008 -#undef LL_APPEND2 -#define LL_APPEND2 LL_APPEND2_VS2008 -#undef LL_CONCAT /* no LL_CONCAT_VS2008 */ -#undef DL_CONCAT /* no DL_CONCAT_VS2008 */ +# undef LL_APPEND +# define LL_APPEND LL_APPEND_VS2008 +# undef LL_DELETE +# define LL_DELETE LL_DELETE_VS2008 +# undef LL_DELETE2 +# define LL_DELETE2 LL_DELETE2_VS2008 +# undef LL_APPEND2 +# define LL_APPEND2 LL_APPEND2_VS2008 +# undef LL_CONCAT /* no LL_CONCAT_VS2008 */ +# undef DL_CONCAT /* no DL_CONCAT_VS2008 */ #endif /* end VS2008 replacements */ -#define LL_COUNT(head,el,counter) \ - LL_COUNT2(head,el,counter,next) \ - -#define LL_COUNT2(head,el,counter,next) { \ - counter = 0; \ - LL_FOREACH2(head,el,next) { ++counter; } \ -} - -#define LL_FOREACH(head,el) \ - LL_FOREACH2(head,el,next) - -#define LL_FOREACH2(head,el,next) \ - for(el=head;el;el=(el)->next) - -#define LL_FOREACH_SAFE(head,el,tmp) \ - LL_FOREACH_SAFE2(head,el,tmp,next) - -#define LL_FOREACH_SAFE2(head,el,tmp,next) \ - for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) - -#define LL_SEARCH_SCALAR(head,out,field,val) \ - LL_SEARCH_SCALAR2(head,out,field,val,next) - -#define LL_SEARCH_SCALAR2(head,out,field,val,next) \ -do { \ - LL_FOREACH2(head,out,next) { \ - if ((out)->field == (val)) break; \ - } \ -} while(0) - -#define LL_SEARCH(head,out,elt,cmp) \ - LL_SEARCH2(head,out,elt,cmp,next) - -#define LL_SEARCH2(head,out,elt,cmp,next) \ -do { \ - LL_FOREACH2(head,out,next) { \ - if ((cmp(out,elt))==0) break; \ - } \ -} while(0) - -#define LL_REPLACE_ELEM(head, el, add) \ -do { \ - LDECLTYPE(head) _tmp; \ - assert(head != NULL); \ - assert(el != NULL); \ - assert(add != NULL); \ - (add)->next = (el)->next; \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - _tmp = head; \ - while (_tmp->next && (_tmp->next != (el))) { \ - _tmp = _tmp->next; \ - } \ - if (_tmp->next) { \ - _tmp->next = (add); \ - } \ - } \ -} while (0) - -#define LL_PREPEND_ELEM(head, el, add) \ -do { \ - LDECLTYPE(head) _tmp; \ - assert(head != NULL); \ - assert(el != NULL); \ - assert(add != NULL); \ - (add)->next = (el); \ - if ((head) == (el)) { \ - (head) = (add); \ - } else { \ - _tmp = head; \ - while (_tmp->next && (_tmp->next != (el))) { \ - _tmp = _tmp->next; \ - } \ - if (_tmp->next) { \ - _tmp->next = (add); \ - } \ - } \ -} while (0) \ +#define LL_COUNT(head, el, counter) LL_COUNT2(head, el, counter, next) + +#define LL_COUNT2(head, el, counter, next) \ + { \ + counter = 0; \ + LL_FOREACH2(head, el, next) { \ + ++counter; \ + } \ + } + +#define LL_FOREACH(head, el) LL_FOREACH2(head, el, next) + +#define LL_FOREACH2(head, el, next) for (el = head; el; el = (el)->next) + +#define LL_FOREACH_SAFE(head, el, tmp) LL_FOREACH_SAFE2(head, el, tmp, next) + +#define LL_FOREACH_SAFE2(head, el, tmp, next) \ + for ((el) = (head); (el) && (tmp = (el)->next, 1); (el) = tmp) + +#define LL_SEARCH_SCALAR(head, out, field, val) \ + LL_SEARCH_SCALAR2(head, out, field, val, next) + +#define LL_SEARCH_SCALAR2(head, out, field, val, next) \ + do { \ + LL_FOREACH2(head, out, next) { \ + if ((out)->field == (val)) \ + break; \ + } \ + } while (0) + +#define LL_SEARCH(head, out, elt, cmp) LL_SEARCH2(head, out, elt, cmp, next) + +#define LL_SEARCH2(head, out, elt, cmp, next) \ + do { \ + LL_FOREACH2(head, out, next) { \ + if ((cmp(out, elt)) == 0) \ + break; \ + } \ + } while (0) + +#define LL_REPLACE_ELEM(head, el, add) \ + do { \ + LDECLTYPE(head) _tmp; \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el)->next; \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ + } while (0) + +#define LL_PREPEND_ELEM(head, el, add) \ + do { \ + LDECLTYPE(head) _tmp; \ + assert(head != NULL); \ + assert(el != NULL); \ + assert(add != NULL); \ + (add)->next = (el); \ + if ((head) == (el)) { \ + (head) = (add); \ + } else { \ + _tmp = head; \ + while (_tmp->next && (_tmp->next != (el))) { \ + _tmp = _tmp->next; \ + } \ + if (_tmp->next) { \ + _tmp->next = (add); \ + } \ + } \ + } while (0) #endif /* UTLIST_H */