BOROSOFTWAREAll work →
scantool/diag_l0_br.c 897 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 * Diag, Layer 0, Interface for B. Roadman BR-1 Interface
24 *
25 * Semi intelligent interface, supports only J1979 properly, and does not
26 * support ISO14230 (KWP2000). In ISO9141-2 mode, only supports the
27 * ISO9141-2 address (0x33h)
28 *
29 *
30 * Thank you to B. Roadman for donation of an interface to the prject
31 *
32 */
33
34#include <assert.h>
35#include <string.h>
36#include <stdio.h>
37#include <stdint.h>
38#include <stdlib.h>
39
40#include "diag.h"
41#include "diag_cfg.h"
42#include "diag_err.h"
43#include "diag_tty.h"
44#include "diag_l0.h"
45#include "diag_l1.h"
46
47
48extern const struct diag_l0 diag_l0_br;
49
50/*
51 * States
52 */
53enum BR_STATE {BR_STATE_CLOSED, BR_STATE_KWP_SENDKB1,
54 BR_STATE_KWP_SENDKB2, BR_STATE_KWP_FASTINIT,
55 BR_STATE_OPEN };
56
57struct br_device {
58 int protocol;
59 int dev_features; /* Device features */
60 enum BR_STATE dev_state; /* State for 5 baud startup stuff */
61 uint8_t dev_kb1; /* KB1/KB2 for 5 baud startup stuff */
62 uint8_t dev_kb2;
63
64
65 uint8_t dev_rxbuf[MAXRBUF]; /* Receive buffer XXX need to be this big? */
66 int dev_rxlen; /* Length of data in buffer */
67 int dev_rdoffset; /* Offset to read from to */
68
69 uint8_t dev_txbuf[16]; /* Copy of last sent frame */
70 unsigned int dev_txlen; /* And length */
71
72 uint8_t dev_framenr; /* Frame nr for vpw/pwm */
73
74 struct cfgi port;
75 ttyp *tty_int; /** handle for tty stuff */
76};
77
78/*
79 * Device features (depends on s/w version on the BR-1 device)
80 */
81#define BR_FEATURE_2BYTE 0x01 /* 2 byte initialisation responses */
82#define BR_FEATURE_SETADDR 0x02 /* User can specifiy ISO address */
83#define BR_FEATURE_FASTINIT 0x04 /* ISO14230 fast init supported */
84
85
86static int br_getmsg(struct diag_l0_device *dl0d,
87 uint8_t *dp, unsigned int timeout);
88
89static int br_initialise(struct diag_l0_device *dl0d,
90 uint8_t type, uint8_t addr);
91
92static int br_writemsg(struct diag_l0_device *dl0d,
93 uint8_t type, const void *dp, size_t txlen);
94
95static void br_close(struct diag_l0_device *dl0d);
96
97/* Types for writemsg - corresponds to top bit values for the control byte */
98#define BR_WRTYPE_DATA 0x00
99#define BR_WRTYPE_INIT 0x40
100
101/*
102 * Init must be callable even if no physical interface is
103 * present, it's just here for the code to initialise its
104 * variables, etc.
105 */
106static int br_init(void) {
107 /* Global init flag */
108 static int br_initdone=0;
109
110 if (br_initdone) {
111 return 0;
112 }
113
114 br_initdone = 1;
115
116 return 0;
117}
118
119static int br_new(struct diag_l0_device *dl0d) {
120 struct br_device *dev;
121 int rv;
122
123 assert(dl0d);
124
125 rv = diag_calloc(&dev, 1);
126 if (rv != 0) {
127 return diag_ifwderr(rv);
128 }
129
130 dl0d->l0_int = dev;
131
132 rv = diag_cfgn_tty(&dev->port);
133 if (rv != 0) {
134 free(dev);
135 return diag_ifwderr(rv);
136 }
137
138 dev->port.next = NULL;
139
140 return 0;
141}
142
143static void br_del(struct diag_l0_device *dl0d) {
144 struct br_device *dev;
145
146 assert(dl0d);
147
148 dev = dl0d->l0_int;
149 if (!dev) {
150 return;
151 }
152
153 diag_cfg_clear(&dev->port);
154 free(dev);
155 return;
156}
157
158static struct cfgi *br_getcfg(struct diag_l0_device *dl0d) {
159 struct br_device *dev;
160 if (dl0d == NULL) {
161 return diag_pseterr(DIAG_ERR_BADCFG);
162 }
163
164 dev = dl0d->l0_int;
165 return &dev->port;
166}
167
168static void br_close(struct diag_l0_device *dl0d) {
169 if (!dl0d) {
170 return;
171 }
172
173 struct br_device *dev = dl0d->l0_int;
174
175 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_CLOSE, DIAG_DBGLEVEL_V,
176 FLFMT "link %p closing\n", FL, (void *)dl0d);
177
178 diag_tty_close(dev->tty_int);
179 dev->tty_int = NULL;
180 dl0d->opened = 0;
181
182 return;
183}
184
185static int br_write(struct diag_l0_device *dl0d, const void *dp, size_t txlen) {
186 struct br_device *dev = dl0d->l0_int;
187
188 if (txlen == 0) {
189 return diag_iseterr(DIAG_ERR_BADLEN);
190 }
191
192 if (diag_tty_write(dev->tty_int, dp, txlen) != (int) txlen) {
193 fprintf(stderr, FLFMT "br_write error\n", FL);
194 return diag_iseterr(DIAG_ERR_GENERAL);
195 }
196
197 return 0;
198}
199
200/*
201 * Open the diagnostic device, return a file descriptor,
202 * record the original state of term interface so we can restore later
203 */
204static int br_open(struct diag_l0_device *dl0d, int iProtocol) {
205 struct br_device *dev = dl0d->l0_int;
206 int rv;
207 uint8_t buf[4]; /* Was MAXRBUF. We only use 1! */
208 struct diag_serial_settings set;
209
210 br_init();
211
212 dev->protocol = iProtocol;
213 dev->dev_rdoffset = 0;
214 dev->dev_txlen = 0;
215 dev->dev_framenr = 0;
216 dev->dev_state = BR_STATE_CLOSED;
217 dev->dev_features = BR_FEATURE_SETADDR;
218
219 /* try to open TTY */
220 dev->tty_int = diag_tty_open(dev->port.val.str);
221 if (dev->tty_int == NULL) {
222 return diag_iseterr(DIAG_ERR_GENERAL);
223 }
224
225 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_OPEN, DIAG_DBGLEVEL_V,
226 FLFMT "features 0x%X\n", FL, dev->dev_features);
227
228 /* Set serial line to 19200 baud , 8N1 */
229 set.speed = 19200;
230 set.databits = diag_databits_8;
231 set.stopbits = diag_stopbits_1;
232 set.parflag = diag_par_n;
233
234 if (diag_tty_setup(dev->tty_int, &set)) {
235 fprintf(stderr, FLFMT "open: TTY setup failed\n", FL);
236 br_close(dl0d);
237 return diag_iseterr(DIAG_ERR_GENERAL);
238 }
239
240 diag_tty_iflush(dev->tty_int); /* Flush unread input data */
241
242 /*
243 * Initialise the BR1 interface by sending the CHIP CONNECT
244 * (0x20h) command, we should get a 0xFF back
245 */
246 buf[0] = 0x20;
247 if (br_write(dl0d, buf, 1)) {
248 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_OPEN, DIAG_DBGLEVEL_V,
249 FLFMT "CHIP CONNECT write failed link %p\n",
250 FL, (void *)dl0d);
251
252 br_close(dl0d);
253 return diag_iseterr(DIAG_ERR_BADIFADAPTER);
254 }
255 /* And expect 0xff as a response */
256 if (diag_tty_read(dev->tty_int, buf, 1, 100) != 1) {
257 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_OPEN, DIAG_DBGLEVEL_V,
258 FLFMT "CHIP CONNECT read failed link %p\n",
259 FL, (void *)dl0d);
260
261 br_close(dl0d);
262 return diag_iseterr(DIAG_ERR_BADIFADAPTER);
263 }
264 if (buf[0] != 0xff) {
265 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_OPEN, DIAG_DBGLEVEL_V,
266 FLFMT "CHIP CONNECT rcvd 0x%X != 0xff, link %p\n",
267 FL, buf[0], (void *)dl0d);
268
269 br_close(dl0d);
270 return diag_iseterr(DIAG_ERR_BADIFADAPTER);
271 }
272
273 /* If it's J1850, send initialisation string now */
274 rv = 0;
275 switch (iProtocol) {
276 case DIAG_L1_J1850_VPW:
277 rv = br_initialise(dl0d, 0, 0);
278 break;
279 case DIAG_L1_J1850_PWM:
280 rv = br_initialise(dl0d, 1, 0);
281 break;
282 case DIAG_L1_ISO9141:
283 case DIAG_L1_ISO14230:
284 /* This initialisation is done in the SLOWINIT code */
285 break;
286 }
287 if (rv) {
288 br_close(dl0d);
289 return diag_ifwderr(rv);
290 }
291
292 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_OPEN, DIAG_DBGLEVEL_V,
293 FLFMT "open succeeded link %p features 0x%X\n",
294 FL, (void *)dl0d, dev->dev_features);
295
296 dl0d->opened = 1;
297 return 0;
298}
299
300
301/*
302 * Do BR interface protocol initialisation,
303 * returns -1 on error or the keybyte value
304 */
305static int br_initialise(struct diag_l0_device *dl0d, uint8_t type, uint8_t addr) {
306 struct br_device *dev =
307 (struct br_device *)dl0d->l0_int;
308
309 uint8_t txbuf[3];
310 uint8_t rxbuf[MAXRBUF];
311 int rv;
312 unsigned int timeout;
313
314
315 /*
316 * Send initialisation message, 42H 0YH
317 * - where Y is iniitialisation type
318 */
319 memset(txbuf, 0, sizeof(txbuf));
320 txbuf[0] = 0x41;
321 txbuf[1] = type;
322 txbuf[2] = addr;
323
324 if (type == 0x02) {
325 timeout = 6000; /* 5 baud init is slow */
326 if (dev->dev_features & BR_FEATURE_SETADDR) {
327 txbuf[0] = 0x42;
328 rv = br_write(dl0d, txbuf, 3);
329 } else {
330 rv = br_write(dl0d, txbuf, 2);
331 }
332 if (rv) {
333 return diag_ifwderr(rv);
334 }
335 } else {
336 timeout = 100;
337 rv = br_write(dl0d, txbuf, 2);
338 if (rv) {
339 return diag_ifwderr(rv);
340 }
341 }
342
343 /*
344 * And get back the fail/success message
345 */
346 if ((rv = br_getmsg(dl0d, rxbuf, timeout)) < 0) {
347 return diag_ifwderr(rv);
348 }
349
350 /*
351 * Response length tells us whether this is an orginal style
352 * interface or one that supports ISO14230 fast init and ISO9141
353 * 5 baud init address setting. This means that it is vital that
354 * a J1850 initialisation request was done before a 9141 one ...
355 */
356 dev->dev_features = 0;
357 switch (rv) {
358 case 1:
359 dev->dev_features |= BR_FEATURE_SETADDR; /* All allow this */
360 break;
361 case 2:
362 dev->dev_features |= BR_FEATURE_2BYTE;
363 dev->dev_features |= BR_FEATURE_SETADDR;
364 dev->dev_features |= BR_FEATURE_FASTINIT;
365 break;
366 default:
367 return diag_iseterr(DIAG_ERR_BADDATA);
368 }
369
370 return rxbuf[0];
371}
372
373/*
374 * Do 5 Baud initialisation
375 *
376 * This is simple on the BR1 interface, we send the initialisation
377 * string, which is 41H 02H and the interface responds with
378 * a 1 byte message (i.e length byte of 01h followed by one of the
379 * keybytes
380 */
381static int br_slowinit( struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) {
382 struct br_device *dev =
383 (struct br_device *)dl0d->l0_int;
384 /*
385 * Slow init
386 * Build message into send buffer, and calculate checksum
387 */
388 uint8_t buf[16]; //limited by br_writemsg
389 int rv;
390
391 buf[0] = 0x02;
392 buf[1] = in->addr;
393
394 /* Send the initialisation message */
395 if (dev->dev_features & BR_FEATURE_SETADDR) {
396 rv = br_writemsg(dl0d, BR_WRTYPE_INIT, buf, 2);
397 } else {
398 rv = br_writemsg(dl0d, BR_WRTYPE_INIT, buf, 1);
399 }
400 if (rv < 0) {
401 return rv;
402 }
403
404 /* And wait for response */
405 if ((rv = br_getmsg(dl0d, buf, 6000)) < 0) {
406 return rv;
407 }
408
409 /*
410 * Now set the keybytes from what weve sent
411 */
412 if (rv == 1) { /* 1 byte response, old type interface */
413 dev->dev_kb1 = buf[0];
414 dev->dev_kb2 = buf[0];
415 } else {
416 dev->dev_kb1 = buf[0];
417 dev->dev_kb2 = buf[1];
418 }
419
420 /*
421 * And tell read code to report the keybytes on first read
422 */
423 dev->dev_state = BR_STATE_KWP_SENDKB1;
424
425 return 0;
426}
427
428/*
429 * Do wakeup on the bus
430 *
431 * We do this by noting a wakeup needs to be done for the next packet for
432 * fastinit, and doing slowinit now
433 */
434static int br_initbus(struct diag_l0_device *dl0d, struct diag_l1_initbus_args *in) {
435 int rv = 0;
436 struct br_device *dev;
437
438 dev = (struct br_device *)dl0d->l0_int;
439
440 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_IOCTL, DIAG_DBGLEVEL_V,
441 FLFMT "device link %p info %p initbus type %d proto %d\n",
442 FL, (void *)dl0d, (void *)dev, in->type, dev ? dev->protocol : -1);
443
444 if (!dev) {
445 return diag_iseterr(DIAG_ERR_GENERAL);
446 }
447
448 diag_tty_iflush(dev->tty_int); /* Flush unread input */
449
450 switch (in->type) {
451 case DIAG_L1_INITBUS_5BAUD:
452 rv = br_slowinit(dl0d, in);
453 break;
454 case DIAG_L1_INITBUS_FAST:
455 if ((dev->dev_features & BR_FEATURE_FASTINIT) == 0) {
456 /* Fast init Not supported */
457 rv = DIAG_ERR_INIT_NOTSUPP;
458 } else {
459 /* Fastinit done on 1st TX */
460 dev->dev_state = BR_STATE_KWP_FASTINIT;
461 rv = 0;
462 }
463 break;
464 default:
465 rv = DIAG_ERR_INIT_NOTSUPP;
466 break;
467 }
468 return rv? diag_iseterr(rv):0;
469}
470
471/*
472 * Routine to read a whole BR1 message
473 * length of which depends on the first value received.
474 * This also handles "error" messages (top bit of first value set)
475 *
476 * Returns length of received message, or TIMEOUT error, or BUSERROR
477 * if the BR interface tells us theres a congested bus
478 */
479static int br_getmsg(struct diag_l0_device *dl0d, uint8_t *dp, unsigned int timeout) {
480 uint8_t firstbyte;
481 size_t readlen;
482 int rv;
483 struct br_device *dev = dl0d->l0_int;
484
485 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_READ, DIAG_DBGLEVEL_V,
486 FLFMT "link %p getmsg timeout %u\n", FL, (void *)dl0d, timeout);
487
488 /*
489 * First read the 1st byte, using the supplied timeout
490 */
491 rv = diag_tty_read(dev->tty_int, &firstbyte, 1, timeout);
492 if (rv != 1) {
493 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_READ, DIAG_DBGLEVEL_V,
494 FLFMT "link %p getmsg 1st byte timed out\n", FL, (void *)dl0d);
495
496 return diag_ifwderr(rv);
497 }
498
499 /*
500 * Now read data. Maximum is 15 bytes.
501 */
502
503 readlen = firstbyte & 0x0f;
504
505 /*
506 * Reasonable timeout here as the interface told us how
507 * much data to expect, so it should arrive
508 */
509 rv = diag_tty_read(dev->tty_int, dp, readlen, 100);
510 if (rv != (int)readlen) {
511 fprintf(stderr, FLFMT "br_getmsg error\n", FL);
512 return diag_iseterr(DIAG_ERR_GENERAL);
513 }
514
515 DIAG_DBGMDATA(diag_l0_debug, DIAG_DEBUG_READ, DIAG_DBGLEVEL_V, dp, readlen,
516 FLFMT "link %p getmsg read ctl 0x%X data:",
517 FL, (void *)dl0d, firstbyte & 0xff);
518
519 /*
520 * Message read complete, check error flag
521 * Top bit set means error, Bit 6 = VPW/PWM bus
522 * congestion (i.e retry).
523 */
524 if (firstbyte & 0x80) { /* Error indicator */
525 return diag_iseterr(DIAG_ERR_TIMEOUT);
526 }
527
528 if (firstbyte & 0x40) { /* VPW/PWM bus conflict, need to retry */
529 return diag_iseterr(DIAG_ERR_BUSERROR);
530 }
531
532 if (readlen == 0) { /* Should never happen */
533 return diag_iseterr(DIAG_ERR_TIMEOUT);
534 }
535
536 return (int) readlen;
537}
538
539
540/** Write Message routine
541 * Adds the length byte to the data before sending,
542 * and the frame number for VPW/PWM. The type is used to set the top bits
543 * of the control byte
544 *
545 * Returns 0 on success, <0 on error
546 * txlen must be <= 15
547 */
548static int br_writemsg(struct diag_l0_device *dl0d, uint8_t type,
549 const void *dp, size_t txlen) {
550 struct br_device *dev =
551 (struct br_device *)dl0d->l0_int;
552 int rv, j1850mode;
553 uint8_t outb;
554
555 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_WRITE, DIAG_DBGLEVEL_V,
556 FLFMT "device %p link %p sending to BR1\n",
557 FL, (void *)dev, (void *)dl0d);
558
559
560 if (txlen > 15) {
561 return diag_iseterr(DIAG_ERR_BADLEN);
562 }
563
564 if ((dev->protocol == DIAG_L1_J1850_VPW) ||
565 (dev->protocol == DIAG_L1_J1850_PWM)) {
566 j1850mode = 1;
567 outb = (uint8_t) txlen + 1; /* We also send a frame number */
568 } else {
569 j1850mode = 0;
570 outb = (uint8_t) txlen;
571 }
572
573 outb |= type; /* Set the type bits on the control byte */
574
575 /* Send the length byte */
576 rv = br_write(dl0d, &outb, 1);
577 if (rv < 0) {
578 return diag_ifwderr(rv);
579 }
580
581 /* And now the data */
582 DIAG_DBGMDATA(diag_l0_debug, DIAG_DEBUG_WRITE, DIAG_DBGLEVEL_V, dp, txlen,
583 FLFMT "device %p writing data: 0x%X",
584 FL, (void *)dev, (unsigned) outb);
585
586 rv = br_write(dl0d, dp, txlen);
587 if (rv < 0) {
588 return diag_ifwderr(rv);
589 }
590
591 /*
592 * ISO mode is raw pass through. In J1850 we need to send
593 * frame numbers, and keep track of whether we are sending/receiving
594 * in order to receive multiple frames.
595 */
596 if (j1850mode) {
597 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_WRITE, DIAG_DBGLEVEL_V,
598 FLFMT "device %p writing data: 0x%X\n",
599 FL, (void *)dev, (unsigned) dev->dev_framenr & 0xff);
600
601 rv = br_write(dl0d, &dev->dev_framenr, 1);
602 if (rv < 0) {
603 return diag_ifwderr(rv);
604 }
605 }
606 return 0;
607}
608
609
610/*
611 * Send a load of data
612 *
613 * Returns 0 on success, -1 on failure
614 *
615 * This routine will do a fastinit if needed, but all 5 baud inits
616 * will have been done by the slowinit() code
617 */
618static int br_send(struct diag_l0_device *dl0d,
619 const void *data, size_t len) {
620 int rv = 0;
621
622 struct br_device *dev;
623
624 dev = (struct br_device *)dl0d->l0_int;
625
626 if (len == 0) {
627 return diag_iseterr(DIAG_ERR_BADLEN);
628 }
629
630 DIAG_DBGMDATA(diag_l0_debug, DIAG_DEBUG_WRITE, DIAG_DBGLEVEL_V, data, len,
631 FLFMT "device link %p send %ld bytes protocol %d state %d: ",
632 FL, (void *)dl0d, (long)len, dev->protocol, dev->dev_state);
633
634 /*
635 * Special handling for fastinit, we need to collect up the
636 * bytes of the StartComms message sent by the upper layer
637 * when we have a whole message we can then send the request
638 * as part of a special initialisation type
639 */
640 if (dev->dev_state == BR_STATE_KWP_FASTINIT) {
641 uint8_t outbuf[6];
642 if (dev->dev_txlen < 5) {
643 memcpy(&dev->dev_txbuf[dev->dev_txlen], data, len);
644 dev->dev_txlen += len;
645 rv = 0;
646 }
647
648 if (dev->dev_txlen >= 5) {
649 /*
650 * Startcomms request is 5 bytes long - we have
651 * 5 bytes, so now we should send the initialisation
652 */
653 outbuf[0] = 0x03;
654 memcpy(&outbuf[1], dev->dev_txbuf, 5);
655 rv = br_writemsg(dl0d, BR_WRTYPE_INIT,
656 outbuf, 6);
657 /* Stays in FASTINIT state until first read */
658 }
659 } else {
660 /*
661 * Now, keep a copy of the data, and set the framenr to 1
662 * This means the receive code will resend the request if it
663 * wants to get a frame number 2 or 3 or whatever
664 */
665 memcpy(dev->dev_rxbuf, data, len);
666 dev->dev_txlen = len;
667 dev->dev_framenr = 1;
668
669 /* And now encapsulate and send the data */
670 rv = br_writemsg(dl0d, BR_WRTYPE_DATA, data, len);
671 }
672
673 return rv;
674}
675
676/*
677 * Get data (blocking), returns number of bytes read, between 1 and len
678 * If timeout is set to 0, this becomes non-blocking
679 *
680 * This attempts to read whole message, so if we receive any data, timeout
681 * is restarted
682 *
683 * Messages received from the BR1 are of format
684 * <control_byte><data ..>
685 * If control byte is < 16, it's a length byte, else it's a error descriptor
686 */
687static int br_recv(struct diag_l0_device *dl0d,
688 void *data, size_t len, unsigned int timeout) {
689 int xferd, rv, retrycnt;
690 uint8_t *pdata = (uint8_t *)data;
691
692 struct br_device *dev;
693 dev = (struct br_device *)dl0d->l0_int;
694
695 if (!len) {
696 return diag_iseterr(DIAG_ERR_BADLEN);
697 }
698
699 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_READ, DIAG_DBGLEVEL_V,
700 FLFMT
701 "link %p recv upto %ld bytes timeout %u, rxlen %d "
702 "offset %d framenr %d protocol %d state %d\n",
703 FL, (void *)dl0d, (long)len, timeout, dev->dev_rxlen,
704 dev->dev_rdoffset, dev->dev_framenr, dev->protocol,
705 dev->dev_state);
706
707 switch (dev->dev_state) {
708 case BR_STATE_KWP_FASTINIT:
709 /* Extend timeouts */
710 timeout = 300;
711 dev->dev_state = BR_STATE_OPEN;
712 break;
713 case BR_STATE_KWP_SENDKB1:
714 if (len >= 2) {
715 pdata[0] = dev->dev_kb1;
716 pdata[1] = dev->dev_kb2;
717 dev->dev_state = BR_STATE_OPEN;
718 return 2;
719 } else if (len == 1) {
720 *pdata = dev->dev_kb1;
721 dev->dev_state = BR_STATE_KWP_SENDKB2;
722 return 1;
723 }
724 return 0; /* Strange, user asked for 0 bytes */
725 break;
726 case BR_STATE_KWP_SENDKB2:
727 if (len >= 1) {
728 *pdata = dev->dev_kb2;
729 dev->dev_state = BR_STATE_OPEN;
730 return 1;
731 }
732 return 0; /* Strange, user asked for 0 bytes */
733 break;
734 default:
735 //So BR_STATE_CLOSED and BR_STATE_OPEN.
736 // I don't know what's supposed to happen here, so
737 fprintf(stderr, FLFMT "Warning : landed in a strange place. Report this please !\n", FL);
738 return 0;
739 break;
740 }
741
742 switch (dev->protocol) {
743 case DIAG_L1_ISO9141:
744 case DIAG_L1_ISO14230:
745 /* Raw mode */
746 xferd = diag_tty_read(dev->tty_int, data, len, timeout);
747 break;
748 default:
749 /*
750 * PWM/VPW Modes
751 *
752 * If theres stuff on the dev-descriptor, give it back
753 * to the user.
754 * We extend timeouts here because in PWM/VPW
755 * modes the interface tells us if there is a timeout, and
756 * we get out of sync if we dont wait for it.
757 */
758 if (timeout < 500) {
759 timeout = 500;
760 }
761
762 if (dev->dev_rxlen == 0) {
763 /*
764 * No message available, try getting one
765 *
766 * If this is the 2nd read after a send, then
767 * we need to resend the request with the next
768 * frame number to see if any more data is ready
769 */
770 if (dev->dev_framenr > 1) {
771 rv = br_writemsg(dl0d,
772 BR_WRTYPE_DATA,
773 dev->dev_txbuf, (size_t)dev->dev_txlen);
774 if (rv < 0) {
775 return rv;
776 }
777 }
778 dev->dev_framenr++;
779
780 retrycnt = 0;
781 while (1) {
782 dev->dev_rdoffset = 0;
783 rv = br_getmsg(dl0d, dev->dev_rxbuf, timeout);
784 if (rv >= 0) {
785 dev->dev_rxlen = rv;
786 break;
787 }
788 if ((rv != DIAG_ERR_BUSERROR) ||
789 (retrycnt >= 30)) {
790 dev->dev_rxlen = 0;
791 return rv;
792 }
793 /* Need to resend and try again */
794 rv = br_writemsg(dl0d,
795 BR_WRTYPE_DATA, dev->dev_txbuf,
796 (size_t)dev->dev_txlen);
797 if (rv < 0) {
798 return rv;
799 }
800 retrycnt++;
801 }
802 }
803 if (dev->dev_rxlen) {
804 size_t bufbytes = dev->dev_rxlen - dev->dev_rdoffset;
805
806 if (bufbytes <= len) {
807 memcpy(data, &dev->dev_rxbuf[dev->dev_rdoffset], bufbytes);
808 dev->dev_rxlen = dev->dev_rdoffset = 0;
809 return (int) bufbytes;
810 }
811 memcpy(data, &dev->dev_rxbuf[dev->dev_rdoffset], len);
812 dev->dev_rdoffset += len;
813 return (int) len;
814 }
815 xferd = 0;
816 break;
817 }
818
819 /* OK, got whole message */
820 DIAG_DBGMDATA(diag_l0_debug, DIAG_DEBUG_READ, DIAG_DBGLEVEL_V,
821 data, (size_t) xferd,
822 FLFMT "link %p received from BR1: ", FL, (void *)dl0d);
823
824 return xferd;
825}
826
827
828static uint32_t br_getflags(struct diag_l0_device *dl0d) {
829 /*
830 * ISO14230/J1850 protocol does L2 framing, ISO9141 is just
831 * raw, once initialised
832 */
833 struct br_device *dev;
834 uint32_t flags;
835
836 dev = (struct br_device *)dl0d->l0_int;
837
838 flags = DIAG_L1_AUTOSPEED;
839 switch (dev->protocol) {
840 case DIAG_L1_J1850_VPW:
841 case DIAG_L1_J1850_PWM:
842 flags = DIAG_L1_DOESL2FRAME;
843 break;
844 case DIAG_L1_ISO9141:
845 flags = DIAG_L1_SLOW;
846 flags |= DIAG_L1_DOESP4WAIT;
847 break;
848 case DIAG_L1_ISO14230:
849 flags = DIAG_L1_SLOW | DIAG_L1_FAST | DIAG_L1_PREFFAST;
850 flags |= DIAG_L1_DOESP4WAIT;
851 break;
852 }
853
854 DIAG_DBGM(diag_l0_debug, DIAG_DEBUG_PROTO, DIAG_DBGLEVEL_V,
855 FLFMT "getflags link %p proto %d flags 0x%X\n",
856 FL, (void *)dl0d, dev->protocol, flags);
857
858 return flags;
859}
860
861
862static int br_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) {
863 int rv = 0;
864
865 switch (cmd) {
866 case DIAG_IOCTL_IFLUSH:
867 //do nothing
868 rv = 0;
869 break;
870 case DIAG_IOCTL_INITBUS:
871 rv = br_initbus(dl0d, (struct diag_l1_initbus_args *)data);
872 break;
873 default:
874 rv = DIAG_ERR_IOCTL_NOTSUPP;
875 break;
876 }
877
878 return rv;
879}
880
881const struct diag_l0 diag_l0_br = {
882 "B. Roadman BR-1 interface",
883 "BR1",
884 DIAG_L1_J1850_VPW | DIAG_L1_J1850_PWM |
885 DIAG_L1_ISO9141 | DIAG_L1_ISO14230,
886 br_init,
887 br_new,
888 br_getcfg,
889 br_del,
890 br_open,
891 br_close,
892 br_getflags,
893 br_recv,
894 br_send,
895 br_ioctl
896};
897