/* * Timeout, - if we don't send something to the ECU it will timeout * soon, so send it a keepalive message now. */ static void diag_l2_proto_vag_timeout(struct diag_l2_conn *d_l2_conn) { //struct diag_l2_vag *dp; struct diag_msg msg= {0}; uint8_t data[256]; /* int rv;*/ //dp = (struct diag_l2_vag *)d_l2_conn->diag_l2_proto_data; //not used? if (diag_l2_debug & DIAG_DEBUG_TIMER) { fprintf(stderr, FLFMT "timeout impending for %p\n", FL, (void *)d_l2_conn); } msg.data = data; /* * There is no point in checking for errors, or checking * the received response as we cant pass an error back * from here */ /* Send it, important to use l2_send as it updates the timers */ (void)diag_l2_send(d_l2_conn, &msg); /* Get the response in p2max, we use p3min to be more flexible */ (void)diag_l2_recv(d_l2_conn, d_l2_conn->diag_l2_p3min, NULL, NULL); }
static struct diag_msg * diag_l2_proto_vag_request(struct diag_l2_conn *d_l2_conn, struct diag_msg *msg, int *errval) { int rv; struct diag_msg *rmsg = NULL; rv = diag_l2_send(d_l2_conn, msg); if (rv < 0) { *errval = rv; return diag_pseterr(DIAG_ERR_GENERAL); } /* And wait for response */ //XXX this l2_iso9141 function should be re-written for l2_vag; they may be incompatible... rv = diag_l2_proto_iso9141_int_recv(d_l2_conn, 1000); if ((rv >= 0) && d_l2_conn->diag_msg) { /* OK */ rmsg = d_l2_conn->diag_msg; d_l2_conn->diag_msg = NULL; } else { /* Error */ *errval = DIAG_ERR_TIMEOUT; rmsg = NULL; } return rmsg; }
struct diag_msg * 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]; rv = diag_l2_send(d_l2_conn, msg); if (rv < 0) { *errval = rv; return diag_pseterr(DIAG_ERR_GENERAL); } /* And wait for response */ rv = diag_l1_recv (d_l2_conn->diag_link->l2_dl0d, 0, rxbuf, sizeof(rxbuf), 1000); if (rv <= 0) { *errval = rv; return NULL; } /* * Ok, alloc a message */ rmsg = diag_allocmsg((size_t)rv); if (rmsg == NULL) { return diag_pseterr(DIAG_ERR_NOMEM); } memcpy(&rmsg->data, rxbuf, (size_t)rv); /* Data */ rmsg->fmt = 0; rmsg->rxtime = diag_os_getms(); return rmsg; }
//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 * diag_l2_proto_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. *errval=0; rv = diag_l2_send(d_l2_conn, msg); if (rv < 0) { *errval = rv; return diag_pseterr(rv); } while (1) { rv = diag_l2_proto_14230_int_recv(d_l2_conn, d_l2_conn->diag_l2_p2max + 10); if (rv < 0) { *errval = DIAG_ERR_TIMEOUT; return diag_pseterr(rv); } /* * The connection now has the received message data * stored, remove it and deal with it */ rmsg = d_l2_conn->diag_msg; d_l2_conn->diag_msg = NULL; /* Got a Error message */ if (rmsg->data[0] == DIAG_KW2K_RC_NR) { if (rmsg->data[2] == DIAG_KW2K_RC_B_RR) { /* * Msg is busyRepeatRequest * So do a send again (if retries>0) */ 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); } retries--; if (rv < 0) { *errval = rv; return diag_pseterr(rv); } if (diag_l2_debug & DIAG_DEBUG_PROTO) fprintf(stderr, FLFMT "got BusyRepeatRequest: retrying...\n", FL); diag_freemsg(rmsg); continue; } if (rmsg->data[2] == DIAG_KW2K_RC_RCR_RP) { /* * Msg is a requestCorrectlyRcvd-RspPending * so do read again */ if (diag_l2_debug & DIAG_DEBUG_PROTO) fprintf(stderr, FLFMT "got RspPending: retrying...\n", FL); diag_freemsg(rmsg); continue; } /* Some other type of error */ *errval= DIAG_ERR_ECUSAIDNO; break; } else { /* Success */ break; } } /* Return the message to user, who is responsible for freeing it */ return rmsg; }
/* * Timeout, - if we don't send something to the ECU it will timeout * soon, so send it a keepalive message now. */ static void diag_l2_proto_14230_timeout(struct diag_l2_conn *d_l2_conn) { struct diag_l2_14230 *dp; 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); } diag_l2_debug=0; //disable diag_l1_debug=0; diag_l0_debug=0; msg.data = data; /* Prepare the "keepalive" message */ if (dp->modeflags & ISO14230_IDLE_J1978) { /* Idle using J1978 / J1979 keep alive message : SID 1 PID 0 */ msg.len = 2; data[0] = 1; data[1] = 0; } else { /* Idle using ISO "Tester Present" message */ msg.len = 1; msg.dest = 0; /* Use default */ msg.src = 0; /* Use default */ data[0] = DIAG_KW2K_SI_TP; } /* * There is no point in checking for errors, or checking * the received response as we can't pass an error back * from here * TODO: we could at least if NEGRESP was received and warn the user... */ /* Send it, important to use l2_send as it updates the timers */ (void)diag_l2_send(d_l2_conn, &msg); /* * Get the response in p2max, we allow longer, and even * longer on "smart" L2 interfaces */ timeout = d_l2_conn->diag_l2_p2max; if (d_l2_conn->diag_link->l1flags & DIAG_L1_DOESL2FRAME) { if (timeout < SMART_TIMEOUT) timeout += SMART_TIMEOUT; } (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; }
//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 * diag_l2_proto_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. *errval=0; rv = diag_l2_send(d_l2_conn, msg); if (rv < 0) { *errval = rv; return diag_pseterr(rv); } while (1) { /* do read only if no messages pending */ if (!d_l2_conn->diag_msg) { rv = diag_l2_proto_14230_int_recv(d_l2_conn, d_l2_conn->diag_l2_p2max + 10); if (rv < 0) { *errval = DIAG_ERR_TIMEOUT; if (rv == DIAG_ERR_TIMEOUT) { return NULL; } else { return diag_pseterr(rv); } } } /* * The connection now has the received message(s) * stored. Temporarily remove from dl2c */ rmsg = d_l2_conn->diag_msg; d_l2_conn->diag_msg = NULL; /* Check for negative response */ if (rmsg->data[0] != DIAG_KW2K_RC_NR) { /* Success */ break; } if (rmsg->data[2] == DIAG_KW2K_RC_B_RR) { /* * Msg is busyRepeatRequest * So send again (if retries>0). * * Is there any possibility that we would have received 2 messages, * {busyrepeatrequest + a valid (unrelated) response} ? * Not sure, let's simply discard everything. */ diag_freemsg(rmsg); 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); } retries--; if (rv < 0) { *errval = rv; return diag_pseterr(rv); } if (diag_l2_debug & DIAG_DEBUG_PROTO) fprintf(stderr, FLFMT "got BusyRepeatRequest: retrying...\n", FL); continue; } if (rmsg->data[2] == DIAG_KW2K_RC_RCR_RP) { /* * Msg is a requestCorrectlyRcvd-RspPending * so do read again */ if (diag_l2_debug & DIAG_DEBUG_PROTO) fprintf(stderr, FLFMT "got RspPending: retrying...\n", FL); /* reattach the rest of the chain, in case the good response * was already received */ d_l2_conn->diag_msg = rmsg->next; rmsg->next = NULL; diag_freemsg(rmsg); continue; } /* Some other type of error */ *errval= DIAG_ERR_ECUSAIDNO; break; } //while 1 /* Return the message to user, who is responsible for freeing it */ return rmsg; }