BOROSOFTWAREAll work →
scantool/diag_l3_saej1979.c 839 lines
1/*
2 * freediag - Vehicle Diagnostic Utility
3 *
4 *
5 * Copyright (C) 2001 Richard Almeida & Ibex Ltd ([email protected])
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *************************************************************************
22 *
23 * L3 code to do SAE J1979 messaging
24 *
25 */
26
27
28#include <assert.h>
29#include <stdint.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33
34#include "diag.h"
35#include "diag_os.h"
36#include "diag_err.h"
37#include "diag_l1.h"
38#include "diag_l2.h"
39#include "diag_l3.h"
40#include "diag_l3_saej1979.h"
41#include "utlist.h"
42
43
44/* internal data used by each connection */
45struct l3_j1979_int {
46 uint8_t src; //source address ("tester ID")
47
48 /* Received data buffer, and offset into it */
49 uint8_t rxbuf[MAXRBUF];
50 int rxoffset;
51};
52
53/*
54 * Return the expected J1979 packet length for a given mode byte
55 * This includes *only* up to 7 data bytes (headers and checksum are stripped and
56 * generated in L2)
57 *
58 * XXX DOESN'T COPE WITH in-frame-response - will break check routine as well
59 * Also doesn't support 15765 (CAN) which has more modes.
60 *
61 * Get this wrong and all will fail, it's used to frame the incoming messages
62 * properly
63 */
64static int diag_l3_j1979_getlen(uint8_t *data, int len) {
65 static const int rqst_lengths[] = { -1, 2, 3, 1, 1, 2, 2, 1, 7, 2 };
66 int rv;
67 uint8_t mode;
68
69 if (len < 1) { /* Need at least 1 data byte*/
70 return diag_iseterr(DIAG_ERR_INCDATA);
71 }
72
73 mode = data[0];
74
75 //J1979 specifies 9 modes (0x01 - 0x09) except with iso15765 (CAN) which has 0x0A modes.
76
77 if (mode > 0x49) {
78 return diag_iseterr(DIAG_ERR_BADDATA);
79 }
80
81 if (mode < 0x41) {
82 if (mode <= 9) {
83 return rqst_lengths[mode];
84 }
85 return diag_iseterr(DIAG_ERR_BADDATA);
86 }
87
88 rv = DIAG_ERR_BADDATA;
89
90 //Here, all modes < 0x0A are taken care of.
91 //Modes > 0x40 are responses and therefore need specific treatment
92 //data[1] contains the PID / TID number.
93 switch (mode) {
94 case 0x41:
95 case 0x42: //almost identical modes except PIDS 1,2
96 // Note : mode 2 responses will be +1 longer because of the frame_no byte.
97 if ((data[1] & 0x1f) == 0) {
98 /* return supported PIDs */
99 rv=6; //6.1.2.2
100 break;
101 }
102
103 switch (data[1]) {
104 case 1: //Status. Only with service 01 (mode 0x41)
105 if (mode == 0x42) {
106 rv=DIAG_ERR_BADDATA;
107 } else {
108 rv = 6;
109 }
110 break;
111 case 2: //request freeze DTC. Only with Service 02 (mode=0x42)
112 if (mode == 0x41) {
113 rv = DIAG_ERR_BADDATA;
114 } else {
115 rv = 4;
116 }
117 break;
118 case 3:
119 rv = 4;
120 break;
121 case 0x04:
122 case 0x05:
123 rv=3;
124 break;
125 case 0x06:
126 case 0x07:
127 case 0x08:
128 case 0x09:
129 case 0x55:
130 case 0x56:
131 case 0x57:
132 case 0x58:
133 //XXX For PIDs 0x06 thru 0x09 and 0x55-0x58, there may be an additional data byte based on PID 0x13 / 0x1D results
134 // (presence of a bank3 O2 sensor. Not implemented...
135 rv=3;
136 break;
137 case 0x0A:
138 case 0x0B: //IMAP
139 rv=3;
140 break;
141 case 0x0C: //RPM
142 rv=4;
143 break;
144 case 0x0D: //VSS
145 case 0x0E:
146 case 0x0F: //IAT
147 rv=3;
148 break;
149 case 0x10: //MAF
150 rv=4;
151 break;
152 case 0x11: //TPS
153 case 0x12:
154 case 0x13: //O2Sloc
155 rv = 3;
156 break;
157 case 0x14: //0x14-0x1B:O2 stuff
158 case 0x15:
159 case 0x16:
160 case 0x17:
161 case 0x18:
162 case 0x19:
163 case 0x1A:
164 case 0x1B:
165 rv = 4;
166 break;
167 case 0x1C: //OBD
168 case 0x1D: //O2Sloc
169 case 0x1E:
170 rv = 2;
171 break;
172 case 0x1F: //RUNTM
173 rv = 4;
174 break;
175 //TODO : PIDS 0x21 etc
176 default:
177 /* Sometime add J2190 support (PID>0x1F) */
178 rv = DIAG_ERR_BADDATA;
179 break;
180 } //PIDs for modes 1 and 2
181 //For mode 2 responses, actual length is 1 byte longer than Mode 1 resps because of Frame No
182 if (mode == 0x42 && rv) {
183 rv += 1;
184 }
185 break;
186 case 0x43:
187 rv=7; //6.3.2.4
188 break;
189 case 0x44:
190 rv = 1; //6.4.2.2
191 break;
192 case 0x45:
193 if ((data[1] & 0x1f) == 0) {
194 rv = 7; // Read supported TIDs, 6.5.2.2
195 } else if (data[1] <= 4) {
196 rv=4; //J1979 sec 6.5.2.4 : conditional TIDs.
197 } else {
198 rv = 6; // Request TID result
199 }
200 break;
201 case 0x46:
202 //6.6.2.2 supported PIDs : len=7
203 //6.6.2.4 : 7 bytes; last 2 are "conditional" in meaning only, always present ??
204 case 0x47: //6.7.2.2
205 case 0x48: //6.8.2.1
206 rv = 7;
207 break;
208 case 0x49: //6.9.1
209 if ((data[1] & 0x1f) ==0) {
210 rv=7; //supported INFOTYPES
211 } else if (data[1] & 1) {
212 //INFOTYPE is odd:
213 rv=7;
214 } else {
215 //even
216 rv=3;
217 }
218 break;
219 default:
220 break;
221 }
222 return rv;
223}
224
225
226/*
227 * Send a J1979 packet - we know the length (from looking at the data)
228 * since we're L3, we assume msg->data[0] is the mode (service id), i.e. there
229 * aren't any headers.
230 */
231static int diag_l3_j1979_send(struct diag_l3_conn *d_l3_conn, struct diag_msg *msg) {
232 int rv;
233 struct diag_l2_conn *d_conn;
234 struct l3_j1979_int *l3i = d_l3_conn->l3_int;
235// uint8_t buf[32];
236
237 /* Get l2 connection info */
238 d_conn = d_l3_conn->d_l3l2_conn;
239
240 DIAG_DBGM(diag_l3_debug, DIAG_DEBUG_WRITE, DIAG_DBGLEVEL_V,
241 FLFMT "send %u bytes, l2 flags 0x%X\n",
242 FL, msg->len, d_l3_conn->d_l3l2_flags);
243
244 //and make sure src address was set in msg:
245 if (!msg->src) {
246 msg->src = 0xF1;
247 }
248
249 /* Note source address on 1st send */
250 if (l3i->src == 0) {
251 l3i->src = msg->src;
252 }
253
254 //we can't set destination address because it's L2-defined.
255 // (iso14230 : dest = 0x33 phys;
256 // (iso9141 + J1850 : dest = 0x6A )
257
258
259 /* L2 does framing, adds addressing and CRC, so do nothing else*/
260 rv = diag_l2_send(d_conn, msg);
261
262 return rv;
263}
264
265/*
266 * RX callback, called as data received from L2. If we get a full message,
267 * call L3 callback routine
268 */
269static void diag_l3_rcv_callback(void *handle, struct diag_msg *msg) {
270 /*
271 * Got some data from L2, build it into a L3 message, if
272 * message is complete call next layer callback routine
273 */
274 struct diag_l3_conn *d_l3_conn = (struct diag_l3_conn *)handle;
275 struct l3_j1979_int *l3i = d_l3_conn->l3_int;
276
277 DIAG_DBGM(diag_l3_debug, DIAG_DEBUG_READ, DIAG_DBGLEVEL_V,
278 FLFMT
279 "rcv_callback for %u bytes fmt 0x%X conn rxoffset %d\n",
280 FL, msg->len, msg->fmt, l3i->rxoffset);
281
282 if (msg->fmt & DIAG_FMT_FRAMED) {
283 /* Send data upward if needed */
284 if (d_l3_conn->callback) {
285 d_l3_conn->callback(d_l3_conn->handle, msg);
286 }
287 } else {
288 /* Add data to the receive buffer on the L3 connection */
289 memcpy(&l3i->rxbuf[l3i->rxoffset],
290 msg->data, msg->len); //XXX possible buffer overflow !
291 l3i->rxoffset += msg->len;
292 }
293}
294
295
296/*
297 * Process_data() - this is the routine that works out the framing
298 * of the data , if recv() was always called at the correct time and
299 * in the correct way then we would have one and one complete message
300 * received by the L2 code normally - however, we cant be sure of that
301 * so we employ this algorithm
302 *
303 * Look at the data and try and work out the length of the message based
304 * on the J1979 protocol. Returns length (excluding headers & checksum !)
305 * VVVVVVVV
306 * Note: J1979 doesn't specify particular checksums beyond what 9141 and 14230 already provide,
307 * i.e. a J1979 message is maximum 7 bytes long except on CANBUS.
308 * headers, address and checksum are handled and stripped at the l2 level (9141, 14230, etc);
309 *
310 * Another validity check is comparing message length (expected vs real); not implemented XXX?
311 * Upper levels can also verify that the responses correspond to the requests (i.e. Service ID 0x02 -> 0x42 )
312 * XXX Broken for the moment because I'm moving the header stuff completely out of L3
313 *
314 */
315static void diag_l3_j1979_process_data(struct diag_l3_conn *d_l3_conn) {
316 /* Process the received data into messages if complete */
317 struct diag_msg *msg;
318 int sae_msglen;
319 struct l3_j1979_int *l3i = d_l3_conn->l3_int;
320
321 while (l3i->rxoffset) {
322 int badpacket=0;
323
324 sae_msglen = diag_l3_j1979_getlen(l3i->rxbuf,
325 l3i->rxoffset); //set expected packet length based on SID + TID
326
327 DIAG_DBGMDATA(diag_l3_debug, DIAG_DEBUG_PROTO, DIAG_DBGLEVEL_V,
328 l3i->rxbuf, l3i->rxoffset -1,
329 FLFMT "process_data rxoffset is %d sae_msglen is %ld; \n",
330 FL, l3i->rxoffset, (long)sae_msglen);
331
332 if (sae_msglen < 0 || sae_msglen > 255) {
333 if (sae_msglen == DIAG_ERR_INCDATA) {
334 /* Not enough data in this frame, this isn't catastrophic */
335 return;
336 }
337 /* Duff data received, bad news ! */
338 badpacket = 1;
339 }
340
341 if (badpacket || (sae_msglen <= l3i->rxoffset)) {
342
343 /* Bad packet, or full packet, need to tell user */
344 uint8_t *data = NULL;
345
346 if (diag_calloc(&msg, 1)) {
347 /* Stuffed, no memory, cant do anything */
348 return;
349 }
350
351 if (!badpacket) {
352 if (diag_malloc(&data, (size_t)sae_msglen)) {
353 free(msg);
354 return;
355 }
356 }
357
358 if (badpacket || (data == NULL)) {
359 /* Failure indicated by zero len msg */
360 msg->data = NULL;
361 msg->len = 0;
362 } else {
363 msg->fmt = DIAG_FMT_ISO_FUNCADDR;
364 // XXX This won't do at all !
365 //msg->type = l3i->rxbuf[0]; //nobody checks this
366 msg->dest = l3i->rxbuf[1];
367 msg->src = l3i->rxbuf[2];
368 /* Copy in J1979 part of message */
369 memcpy(data, &l3i->rxbuf[3], (size_t)(sae_msglen - 4));
370 /* remove whole message from rx buf */
371 memmove(l3i->rxbuf,
372 &l3i->rxbuf[sae_msglen],
373 (size_t)sae_msglen);
374
375 l3i->rxoffset -= sae_msglen;
376
377 msg->data = data;
378 msg->len = (uint8_t) sae_msglen - 4;
379 }
380
381 msg->rxtime = diag_os_getms();
382
383 /* Add it to the list */
384 LL_CONCAT(d_l3_conn->msg, msg);
385
386 if (badpacket) {
387 /* No point in continuing */
388 break;
389 }
390 } else {
391 /* Need some more data */
392 break;
393 }
394 }
395}
396
397/*
398 * Receive a J1979 frame (building it as we get small amounts of data)
399 *
400 * - timeout expiry will cause return before complete packet
401 *
402 * Successful packet receive will call the callback routine with the message
403 * XXX currently broken because I'm halfway through modifying _process_data
404 */
405static int diag_l3_j1979_recv(struct diag_l3_conn *d_l3_conn, unsigned int timeout,
406 void (* rcv_call_back)(void *handle,struct diag_msg *), void *handle) {
407 int rv;
408 struct diag_msg *msg;
409 unsigned int tout;
410 int state;
411//State machine:
412#define ST_STATE1 1 // timeout=0 to get data already in buffer
413#define ST_STATE2 2
414#define ST_STATE3 3
415#define ST_STATE4 4
416
417 if (d_l3_conn->d_l3l2_flags & DIAG_L2_FLAG_FRAMED) {
418 /*
419 * L2 does framing stuff , which means we get one message
420 * with nicely formed frames
421 */
422 state = ST_STATE4;
423 } else {
424 state = ST_STATE1;
425 }
426
427 /* Store the callback routine for use if needed */
428 d_l3_conn->callback = rcv_call_back;
429 d_l3_conn->handle = handle;
430
431 /*
432 * This works by doing a read with a timeout of 0, to collect
433 * any data that was present on the link, if no messages complete
434 * then read with the normal timeout, then read with a timeout
435 * of p4max ms until no more data is left (or timeout), then call
436 * the callback routine (if there is a complete message)
437 */
438 while (1) {
439 /* State machine for setting timeout values */
440 switch (state) {
441 case ST_STATE1:
442 tout = 0;
443 break;
444 case ST_STATE2:
445 tout = timeout;
446 break;
447 case ST_STATE3:
448 tout = 5; /* XXX should be p4max */
449 break;
450 case ST_STATE4:
451 tout = timeout;
452 break;
453 default:
454 break;
455 }
456
457 DIAG_DBGM(diag_l3_debug, DIAG_DEBUG_PROTO, DIAG_DBGLEVEL_V,
458 FLFMT "recv state %d tout %u\n",
459 FL, state, tout);
460
461 /*
462 * Call L2 receive, L2 will build up the datapacket and
463 * call the callback routine if needed, we use a timeout
464 * of zero to see if data exists *now*,
465 */
466 rv = diag_l2_recv(d_l3_conn->d_l3l2_conn, tout,
467 diag_l3_rcv_callback, (void *)d_l3_conn);
468
469 DIAG_DBGM(diag_l3_debug, DIAG_DEBUG_PROTO, DIAG_DBGLEVEL_V,
470 FLFMT "recv returns %d\n", FL, rv);
471
472 if ((rv < 0) && (rv != DIAG_ERR_TIMEOUT)) {
473 break; /* Some nasty failure */
474 }
475
476 if (rv == DIAG_ERR_TIMEOUT) {
477 if ( (state == ST_STATE3) || (state == ST_STATE4) ) {
478 /* Finished */
479 break;
480 }
481 if ( (state == ST_STATE1) && (d_l3_conn->msg == NULL) ) {
482 /*
483 * Try again, with real timeout
484 * (and thus sleep)
485 */
486 state = ST_STATE2;
487 tout = timeout;
488 continue;
489 }
490 }
491
492 if (state != ST_STATE4) {
493 /* Process the data into messages */
494 diag_l3_j1979_process_data(d_l3_conn);
495
496 DIAG_DBGM(diag_l3_debug, DIAG_DEBUG_PROTO, DIAG_DBGLEVEL_V,
497 FLFMT "recv process_data called, msg %p\n",
498 FL, (void *)d_l3_conn->msg);
499
500 /*
501 * If there is a full message, remove it, call back
502 * the user call back routine with it, and free it
503 */
504 msg = d_l3_conn->msg;
505 if (msg) {
506 d_l3_conn->msg = msg->next;
507
508 rcv_call_back(handle, msg);
509 diag_freemsg(msg);
510 rv = 0;
511 /* And quit while we are ahead */
512 break;
513 }
514 }
515 /* We do not have a complete message (yet) */
516 if (state == ST_STATE2) {
517 /* Part message, see if we get some more */
518 state = ST_STATE3;
519 }
520 if (state == ST_STATE1) {
521 /* Ok, try again with proper timeout */
522 state = ST_STATE2;
523 }
524 if ((state == ST_STATE3) || (state == ST_STATE4)) {
525 /* Finished, we only do read once in this state */
526 break;
527 }
528 }
529
530 return rv;
531}
532
533
534
535/*
536 * This is called without the ADDR_ADDR_1 on it, ie it contains
537 * just the SAEJ1979 data
538 * Returns a string with the description + data associated with a J1979 message.
539 * Doesn't do any data scaling / conversion.
540 */
541
542void diag_l3_j1979_decode(UNUSED(struct diag_l3_conn *d_l3_conn),
543 struct diag_msg *msg, char *buf, size_t bufsize) {
544 unsigned i, j;
545
546 char buf2[80];
547
548 char area; //for DTCs
549
550 if (msg->data[0] & 0x40) {
551 snprintf(buf, bufsize, "J1979 response ");
552 } else {
553 snprintf(buf, bufsize, "J1979 request ");
554 }
555
556 switch (msg->data[0]) {
557 case 0x01:
558 snprintf(buf2, sizeof(buf2), "Mode 1 PID 0x%02X", msg->data[1]);
559 smartcat(buf, bufsize, buf2);
560 break;
561 case 0x41:
562 snprintf(buf2, sizeof(buf2),"Mode 1 Data: PID 0x%02X ", msg->data[1]);
563 smartcat(buf, bufsize, buf2);
564 for (i=2; i < msg->len; i++) {
565 snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]);
566 smartcat(buf, bufsize, buf2);
567 }
568 break;
569 case 0x02:
570 snprintf(buf2, sizeof(buf2), "Mode 2 PID 0x%02X Frame 0x%02X", msg->data[1],
571 msg->data[2]);
572 smartcat(buf, bufsize, buf2);
573 break;
574 case 0x42:
575 snprintf(buf2, sizeof(buf2),"Mode 2 FreezeFrame Data: PID 0x%02X Frame 0x%02X ",
576 msg->data[1], msg->data[2]);
577 smartcat(buf, bufsize, buf2);
578 for (i=3; i < msg->len; i++) {
579 snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]);
580 smartcat(buf, bufsize, buf2);
581 }
582 break;
583 case 0x03:
584 snprintf(buf2, sizeof(buf2),"Mode 3 (Powertrain DTCs)");
585 smartcat(buf, bufsize, buf2);
586 break;
587 case 0x07:
588 snprintf(buf2, sizeof(buf2),
589 "Request Non-Continuous Monitor System Test Results");
590 smartcat(buf, bufsize, buf2);
591 break;
592 case 0x47:
593 snprintf(buf2, sizeof(buf2), "Non-Continuous Monitor System ");
594 smartcat(buf, bufsize, buf2);
595 /* Fallthru */
596 case 0x43:
597 snprintf(buf2, sizeof(buf2),"DTCs: ");
598 smartcat(buf, bufsize, buf2);
599 for (i=0, j=1; i<3; i++, j+=2) {
600 if ((msg->data[j] == 0) &&
601 (msg->data[j + 1] == 0)) {
602 continue;
603 }
604
605 switch ((msg->data[j] >> 6) & 0x03) {
606 case 0:
607 area = 'P';
608 break;
609 case 1:
610 area = 'C';
611 break;
612 case 2:
613 area = 'B';
614 break;
615 case 3:
616 area = 'U';
617 break;
618 default:
619 fprintf(stderr, "Illegal msg->data[%u] value\n", j);
620 area = 'X';
621 break;
622 }
623 snprintf(buf2, sizeof(buf2), "%c%02X%02X ", area, msg->data[j] & 0x3f,
624 msg->data[j+1]&0xff);
625 smartcat(buf, bufsize, buf2);
626 }
627 break;
628 case 0x04:
629 snprintf(buf2, sizeof(buf2), "Clear DTCs");
630 smartcat(buf, bufsize, buf2);
631 break;
632 case 0x44:
633 snprintf(buf2, sizeof(buf2), "DTCs cleared");
634 smartcat(buf, bufsize, buf2);
635 break;
636 case 0x05:
637 snprintf(buf2, sizeof(buf2), "Oxygen Sensor Test ID 0x%02X Sensor 0x%02X",
638 msg->data[1], msg->data[2]);
639 smartcat(buf, bufsize, buf2);
640 break;
641 case 0x45:
642 snprintf(buf2, sizeof(buf2), "Oxygen Sensor TID 0x%02X Sensor 0x%02X ",
643 msg->data[1], msg->data[2]);
644 smartcat(buf, bufsize, buf);
645 for (i=3; i < msg->len; i++) {
646 snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]);
647 smartcat(buf, bufsize, buf2);
648 }
649 break;
650 case 0x06:
651 snprintf(buf2, sizeof(buf2), "Onboard monitoring test request TID 0x%02X", msg->data[1]);
652 smartcat(buf, bufsize, buf2);
653 break;
654 case 0x46:
655 snprintf(buf2, sizeof(buf2),"Onboard monitoring test result TID 0x%02X ", msg->data[1]);
656 smartcat(buf, bufsize, buf2);
657 for (i=2; i < msg->len; i++) {
658 snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]);
659 smartcat(buf, bufsize, buf2);
660 }
661 break;
662 case 0x08:
663 snprintf(buf2, sizeof(buf2), "Request control of onboard system TID 0x%02X", msg->data[1]);
664 smartcat(buf, bufsize, buf2);
665 break;
666 case 0x48:
667 snprintf(buf2, sizeof(buf2), "Control of onboard system response TID 0x%02X ", msg->data[1]);
668 smartcat(buf, bufsize, buf2);
669 for (i=2; i < msg->len; i++) {
670 snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]);
671 smartcat(buf, bufsize, buf2);
672 }
673 break;
674 case 0x09:
675 snprintf(buf2, sizeof(buf2), "Request vehicle information infotype 0x%02X", msg->data[1]);
676 smartcat(buf, bufsize, buf2);
677 break;
678 case 0x49:
679 snprintf(buf2, sizeof(buf2), "Vehicle information infotype 0x%02X ", msg->data[1]);
680 smartcat(buf, bufsize, buf2);
681 for (i=2; i < msg->len; i++) {
682 snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]);
683 smartcat(buf, bufsize, buf2);
684 }
685 break;
686 default:
687 snprintf(buf2, sizeof(buf2),"UnknownType 0x%02X: Data Dump: ", msg->data[0]);
688 smartcat(buf, bufsize, buf2);
689 for (i=0; i < msg->len; i++) {
690 snprintf(buf2, sizeof(buf2), "0x%02X ", msg->data[i]);
691 smartcat(buf, bufsize, buf2);
692 }
693 }
694 return;
695}
696
697
698//Send a service 1, pid 0 request and check for a valid reply.
699//ret 0 if ok
700static int diag_l3_j1979_keepalive(struct diag_l3_conn *d_l3_conn) {
701 struct diag_msg msg = {0};
702 struct diag_msg *rxmsg;
703 uint8_t data[6];
704 int errval;
705 struct l3_j1979_int *l3i = d_l3_conn->l3_int;
706
707 /*
708 * Service 1 Pid 0 request is the SAEJ1979 idle message
709 * XXX Need to get the address bytes correct
710 */
711 msg.len = 2;
712 data[0] = 1; /* Mode 1 */
713 data[1] = 0; /* Pid 0 */
714 msg.data = data;
715
716 /*
717 * And set the source address, if no sends have happened, then
718 * the src address will be 0, so use the default used in J1979
719 */
720 if (l3i->src) {
721 msg.src = l3i->src;
722 } else {
723 msg.src = 0xF1; /* Default as used in SAE J1979 */
724 }
725
726 /* Send it: using l3_request() makes sure the connection's timestamp is updated */
727 rxmsg=diag_l3_request(d_l3_conn, &msg, &errval);
728
729 if (rxmsg == NULL) {
730 return diag_ifwderr(errval);
731 }
732
733 DIAG_DBGM(diag_l3_debug, DIAG_DEBUG_PROTO, DIAG_DBGLEVEL_V,
734 FLFMT "keepalive : got %u bytes, %02X ...\n",
735 FL, rxmsg->len, rxmsg->data[0]);
736
737 /* Check if its a valid SID 1 PID 0 response */
738 if ((rxmsg->len < 1) || (rxmsg->data[0] != 0x41)) {
739 diag_freemsg(rxmsg);
740 return diag_iseterr(DIAG_ERR_ECUSAIDNO);
741 }
742
743 diag_freemsg(rxmsg);
744 return 0;
745
746}
747
748//_start : send service 1 pid 0 request (J1979 keepalive); according to SAE J1979 (p.7) :
749// " IMPORTANT - All emissions-related OBD ECUs which at least support one of the services defined in this
750// document shall support service $01 and PID $00. Service $01 with PID $00 is defined as the universal
751// "initialisation/keep alive/ping" message for all emissions-related OBD ECUs. "
752//That sounds like a sure-fire way to make sure we have a succesful connection to a J1979-compliant ECU.
753int diag_l3_j1979_start(struct diag_l3_conn *d_l3_conn) {
754 int rv;
755 struct l3_j1979_int *l3i;
756
757 assert(d_l3_conn != NULL);
758
759 rv = diag_calloc(&l3i, 1);
760 if (rv != 0) {
761 return diag_ifwderr(rv);
762 }
763
764 d_l3_conn->l3_int = l3i;
765
766 rv=diag_l3_j1979_keepalive(d_l3_conn);
767
768 if (rv<0) {
769 fprintf(stderr, FLFMT "J1979 Keepalive failed ! Try to disconnect and reconnect.\n", FL);
770 free(l3i);
771 return diag_ifwderr(rv);
772 }
773
774
775 return 0;
776}
777
778/* Stop communications : nothing defined, other than letting the link timeout (L2 defined). */
779int dl3_j1979_stop(struct diag_l3_conn *d_l3_conn) {
780 assert(d_l3_conn != NULL);
781 free(d_l3_conn->l3_int);
782 return 0;
783}
784
785/*
786 * Timer routine, called with time (in ms) since the "timer" value in
787 * the L3 structure
788 * return 0 if ok
789 */
790static int diag_l3_j1979_timer(struct diag_l3_conn *d_l3_conn, unsigned long ms) {
791 int rv;
792 int debug_l2_orig=diag_l2_debug; //save debug flags; disable them for this procedure
793 int debug_l1_orig=diag_l1_debug;
794
795 /* J1979 needs keepalive at least every 5 seconds (P3), we use 3.5s */
796
797 assert(d_l3_conn != NULL);
798 if (ms < J1979_KEEPALIVE) {
799 return 0;
800 }
801
802 /* Does L2 do keepalive for us ? */
803 if (d_l3_conn->d_l3l2_flags & DIAG_L2_FLAG_KEEPALIVE) {
804 return 0;
805 }
806
807 /* OK, do keep alive on this connection */
808 /* XXX Not async-signal-safe */
809 DIAG_DBGM(diag_l3_debug, DIAG_DEBUG_TIMER, DIAG_DBGLEVEL_V,
810 FLFMT "\nP3 timeout impending for %p %lu ms\n",
811 FL, (void *)d_l3_conn, ms);
812
813 diag_l2_debug=0; //disable
814 diag_l1_debug=0;
815
816 rv=diag_l3_j1979_keepalive(d_l3_conn);
817
818 if (rv<0) {
819 fprintf(stderr, FLFMT "J1979 Keepalive failed ! Try to disconnect and reconnect.\n", FL);
820 }
821
822 diag_l2_debug=debug_l2_orig; //restore debug flags
823 diag_l1_debug=debug_l1_orig;
824
825 return rv;
826}
827
828const struct diag_l3_proto diag_l3_j1979 = {
829 "SAEJ1979",
830 diag_l3_j1979_start,
831 dl3_j1979_stop,
832 diag_l3_j1979_send,
833 diag_l3_j1979_recv,
834 NULL, //ioctl
835 diag_l3_base_request,
836 diag_l3_j1979_decode,
837 diag_l3_j1979_timer
838};
839