rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
isotp.cpp
Go to the documentation of this file.
1/**
2 *
3 * https://en.wikipedia.org/wiki/ISO_15765-2
4 */
5
6#include "pch.h"
7#include "isotp.h"
8#include "can_rx.h"
9
10#if HAL_USE_CAN || EFI_UNIT_TEST
11
12static const size_t maxDlc = 8;
13
14int IsoTpBase::sendFrame(const IsoTpFrameHeader &header, const uint8_t *data, int num, can_sysinterval_t timeout) {
15 // Calculate needed DLC and maximum payload
16 int offset, numBytes;
17 switch (header.frameType) {
20 numBytes = minI(num, maxDlc - offset);
21 break;
24 numBytes = minI(num, maxDlc - offset);
25 break;
28 numBytes = minI(num, maxDlc - offset);
29 break;
32 numBytes = 0; // no data is sent with 'flow control' frame
33 break;
34 default:
35 // bad frame type
36 return 0;
37 }
38
39 int dlc = offset + numBytes;
40 CanTxMessage txmsg(CanCategory::SERIAL, txFrameId, dlc, busIndex, IS_EXT_RANGE_ID(txFrameId));
41
42 // fill the frame data according to the CAN-TP protocol (ISO 15765-2)
43 txmsg[isoHeaderByteIndex] = (uint8_t)((header.frameType & 0xf) << 4);
44 switch (header.frameType) {
46 txmsg[isoHeaderByteIndex] |= numBytes;
47 break;
49 txmsg[isoHeaderByteIndex] |= (header.numBytes >> 8) & 0xf;
50 txmsg[isoHeaderByteIndex + 1] = (uint8_t)(header.numBytes & 0xff);
51 break;
53 txmsg[isoHeaderByteIndex] |= header.index & 0xf;
54 break;
56 txmsg[isoHeaderByteIndex] |= header.fcFlag & 0xf;
57 txmsg[isoHeaderByteIndex + 1] = (uint8_t)(header.blockSize);
58 txmsg[isoHeaderByteIndex + 2] = (uint8_t)(header.separationTime);
59 break;
60 default:
61 // bad frame type
62 return 0;
63 }
64
65 // copy the contents
66 if (data != nullptr) {
67 for (int i = 0; i < numBytes; i++) {
68 txmsg[i + offset] = data[i];
69 }
70 }
71
72 // send the frame!
73 if (transmit(txmsg, timeout) == CAN_MSG_OK) {
74 return numBytes;
75 }
76
77 return 0;
78}
79
81 IsoTpFrameHeader header;
83 header.fcFlag = 0; // = "continue to send"
84 header.blockSize = 0; // = the remaining "frames" to be sent without flow control or delay
85 header.separationTime = 0; // = wait 0 milliseconds, send immediately
86 sendFrame(header, nullptr, 0, timeout);
87}
88
89// returns the number of copied bytes
90int CanStreamerState::receiveFrame(const CANRxFrame &rxmsg, uint8_t *destinationBuff, int availableAtBuffer, can_sysinterval_t timeout) {
91 if (rxmsg.DLC < 1 + isoHeaderByteIndex)
92 return 0;
94 int frameType = (rxmsg.data8[isoHeaderByteIndex] >> 4) & 0xf;
96 efiPrintf("receiveFrame frameType=%d", frameType);
97#if EFI_PROD_CODE
98 printCANRxFrame(-1, rxmsg);
99#endif // EFI_PROD_CODE
100 }
101 int numBytesAvailable, frameIdx;
102 const uint8_t *srcBuf;
103 switch (frameType) {
105 numBytesAvailable = rxmsg.data8[isoHeaderByteIndex] & 0xf;
106 this->waitingForNumBytes = numBytesAvailable;
107 srcBuf = rxmsg.data8 + 1 + isoHeaderByteIndex;
108 break;
110 this->waitingForNumBytes = ((rxmsg.data8[isoHeaderByteIndex] & 0xf) << 8) | rxmsg.data8[isoHeaderByteIndex + 1];
111 this->waitingForFrameIndex = 1;
112 numBytesAvailable = minI(this->waitingForNumBytes, 6 - isoHeaderByteIndex);
113 srcBuf = rxmsg.data8 + 2 + isoHeaderByteIndex;
114 if (rxTransport) {
115 rxTransport->onTpFirstFrame(); // used to send flow control message
116 }
117 break;
119 frameIdx = rxmsg.data8[isoHeaderByteIndex] & 0xf;
120 if (this->waitingForNumBytes < 0 || this->waitingForFrameIndex != frameIdx) {
121 // todo: that's an abnormal situation, and we probably should react?
122 return 0;
123 }
124 numBytesAvailable = minI(this->waitingForNumBytes, 7 - isoHeaderByteIndex);
125 srcBuf = rxmsg.data8 + 1 + isoHeaderByteIndex;
126 this->waitingForFrameIndex = (this->waitingForFrameIndex + 1) & 0xf;
127 break;
129 // todo: currently we just ignore the FC frame
130 return 0;
131 default:
132 // bad frame type
133 return 0;
134 }
135
136/** performance optimization specific to TS over CAN tunnelling
137TODO: refactor into child class if we ever choose to revive this logic
138#if defined(TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME)
139 if (frameType == ISO_TP_FRAME_SINGLE) {
140 // restore the CRC on the whole packet
141 uint32_t crc = crc32((void *) srcBuf, numBytesAvailable);
142 // we need a separate buffer for crc because srcBuf may not be word-aligned for direct copy
143 uint8_t crcBuffer[sizeof(uint32_t)];
144 *(uint32_t *) (crcBuffer) = SWAP_UINT32(crc);
145
146 // now set the packet size
147 *(uint16_t *) shortCrcPacketStagingArea = SWAP_UINT16(numBytesAvailable);
148 // copy the data
149 if (numBytesAvailable > 0)
150 memcpy(shortCrcPacketStagingArea + sizeof(uint16_t), srcBuf, numBytesAvailable);
151 // copy the crc to the end
152 memcpy(shortCrcPacketStagingArea + sizeof(uint16_t) + numBytesAvailable, crcBuffer, sizeof(crcBuffer));
153
154 // use the reconstructed tmp buffer as a source buffer
155 srcBuf = shortCrcPacketStagingArea;
156 // we added the 16-bit size & 32-bit crc bytes
157 numBytesAvailable += sizeof(uint16_t) + sizeof(crcBuffer);
158 }
159#endif *//* TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME */
160
161 int numBytesToCopy = minI(availableAtBuffer, numBytesAvailable);
162 if (destinationBuff != nullptr) {
163 memcpy(destinationBuff, srcBuf, numBytesToCopy);
164 }
165 srcBuf += numBytesToCopy;
166 waitingForNumBytes -= numBytesAvailable;
168 numBytesAvailable -= numBytesToCopy;
169 // if there are some more bytes left, we save them for the next time
170 for (int i = 0; i < numBytesAvailable; i++) {
171 rxFifoBuf.put(srcBuf[i]);
172 }
173
174 // according to the specs, we need to acknowledge the received multi-frame start frame
175 if (frameType == ISO_TP_FRAME_FIRST) {
176 sendFlowControl(timeout);
177 }
178
179 return numBytesToCopy;
180}
181
187
188int CanStreamerState::sendDataTimeout(const uint8_t *txbuf, int numBytes, can_sysinterval_t timeout) {
189 int offset = 0;
190
192 PRINT("*** INFO: sendDataTimeout %d" PRINT_EOL, numBytes);
193 }
194
195 if (numBytes < 1)
196 return 0;
197
198 // 1 frame
199 if (numBytes <= 7 - isoHeaderByteIndex) {
200 IsoTpFrameHeader header;
202 header.numBytes = numBytes;
203 return IsoTpBase::sendFrame(header, txbuf, numBytes, timeout);
204 }
205
206 // multiple frames
207
208 // send the first header frame (FF)
209 IsoTpFrameHeader header;
211 header.numBytes = numBytes;
212 int numSent = IsoTpBase::sendFrame(header, txbuf + offset, numBytes, timeout);
213 offset += numSent;
214 numBytes -= numSent;
215
216 // get a flow control (FC) frame
217#if !EFI_UNIT_TEST // todo: add FC to unit-tests?
218 CANRxFrame rxmsg;
219 for (size_t numFcReceived = 0; ; numFcReceived++) {
220 if (rxTransport->receive(&rxmsg, timeout) != CAN_MSG_OK) {
221#ifdef SERIAL_CAN_DEBUG
222 PRINT("*** ERROR: CAN Flow Control frame not received" PRINT_EOL);
223#endif /* SERIAL_CAN_DEBUG */
224 //warning(ObdCode::CUSTOM_ERR_CAN_COMMUNICATION, "CAN Flow Control frame not received");
225 return 0;
226 }
227 receiveFrame(rxmsg, nullptr, 0, timeout);
228 uint8_t frameType = (rxmsg.data8[isoHeaderByteIndex] >> 4) & 0xf;
229 uint8_t flowStatus = rxmsg.data8[isoHeaderByteIndex] & 0xf;
230 // if something is not ok
231 if ((frameType != ISO_TP_FRAME_FLOW_CONTROL) || (flowStatus != CAN_FLOW_STATUS_OK)) {
232 // if the receiver is not ready yet and asks to wait for the next FC frame (give it 3 attempts)
233 if ((frameType == ISO_TP_FRAME_FLOW_CONTROL) && (flowStatus == CAN_FLOW_STATUS_WAIT_MORE) && (numFcReceived < 3)) {
234 continue;
235 }
236#ifdef SERIAL_CAN_DEBUG
237 efiPrintf("*** ERROR: CAN Flow Control mode not supported");
238#endif /* SERIAL_CAN_DEBUG */
239 //warning(ObdCode::CUSTOM_ERR_CAN_COMMUNICATION, "CAN Flow Control mode not supported");
240 return 0;
241 }
242 uint8_t blockSize = rxmsg.data8[isoHeaderByteIndex + 1];
243 uint8_t minSeparationTime = rxmsg.data8[isoHeaderByteIndex + 2];
244 if (blockSize != 0 || minSeparationTime != 0) {
245 // todo: process other Flow Control fields (see ISO 15765-2)
246#ifdef SERIAL_CAN_DEBUG
247 efiPrintf("*** ERROR: CAN Flow Control fields not supported");
248#endif /* SERIAL_CAN_DEBUG */
249 //warning(ObdCode::CUSTOM_ERR_CAN_COMMUNICATION, "CAN Flow Control fields not supported");
250 }
251 break;
252 }
253#endif /* EFI_UNIT_TEST */
254
255 // send the rest of the data
256 int idx = 1;
257 while (numBytes > 0) {
258 int len = minI(numBytes, 7 - isoHeaderByteIndex);
259 // send the consecutive frames
261 header.index = ((idx++) & 0x0f);
262 header.numBytes = len;
263 numSent = IsoTpBase::sendFrame(header, txbuf + offset, len, timeout);
264 if (numSent < 1)
265 break;
266 offset += numSent;
267 numBytes -= numSent;
268 }
269 return offset;
270}
271
272int CanStreamerState::getDataFromFifo(uint8_t *rxbuf, size_t &numBytes) {
273 if (rxFifoBuf.isEmpty())
274 return 0;
275 int numReadFromFifo = minI(numBytes, rxFifoBuf.getCount());
276 // move bytes from the FIFO buffer
277 int i;
278 for (i = 0; !rxFifoBuf.isEmpty() && i < numReadFromFifo; i++) {
279 rxbuf[i] = rxFifoBuf.get();
280 numBytes--;
281 }
282 return i;
283}
284
285can_msg_t CanStreamerState::streamAddToTxTimeout(size_t *np, const uint8_t *txbuf, can_sysinterval_t timeout) {
286 int numBytes = *np;
287 int offset = 0;
288
290 PRINT("*** INFO: streamAddToTxTimeout adding %d, in buffer %d" PRINT_EOL, numBytes, txFifoBuf.getCount());
291 }
292
293 // we send here only if the TX FIFO buffer is getting overflowed
294 while (numBytes >= txFifoBuf.getSize() - txFifoBuf.getCount()) {
295 int numBytesToAdd = txFifoBuf.getSize() - txFifoBuf.getCount();
296 txFifoBuf.put(txbuf + offset, numBytesToAdd);
297 int numSent = sendDataTimeout((const uint8_t *)txFifoBuf.getElements(), txFifoBuf.getCount(), timeout);
298
300 PRINT("*** INFO: streamAddToTxTimeout numBytesToAdd %d / numSent %d / numBytes %d" PRINT_EOL, numBytesToAdd, numSent, numBytes);
301 }
302
303 if (numSent < 1)
304 break;
305 txFifoBuf.clear();
306 offset += numBytesToAdd;
307 numBytes -= numBytesToAdd;
308 }
309
311 PRINT("*** INFO: streamAddToTxTimeout remaining goes to buffer %d" PRINT_EOL, numBytes);
312 }
313
314 // now we put the rest on hold
315 txFifoBuf.put(txbuf + offset, numBytes);
316
317
319 PRINT("*** INFO: in buffer %d" PRINT_EOL, txFifoBuf.getCount());
320 }
321
322 return CAN_MSG_OK;
323}
324
326 int numSent = sendDataTimeout((const uint8_t *)txFifoBuf.getElements(), txFifoBuf.getCount(), timeout);
327 if (numSent != txFifoBuf.getCount()) {
328 //warning(ObdCode::CUSTOM_ERR_CAN_COMMUNICATION, "CAN sendDataTimeout() problems");
329 }
330 txFifoBuf.clear();
331
332 return CAN_MSG_OK;
333}
334
336 size_t availableBufferSpace = *np;
337
338 // first, fill the data from the stored buffer (saved from the previous CAN frame)
339 int receivedSoFar = getDataFromFifo(rxbuf, availableBufferSpace);
340
341 // if even more data is needed, then we receive more CAN frames
342 while (availableBufferSpace > 0) {
343 CANRxFrame rxmsg;
344 if (rxTransport->receive(&rxmsg, timeout) == CAN_MSG_OK) {
345 int numReceived = receiveFrame(rxmsg, rxbuf + receivedSoFar, availableBufferSpace, timeout);
346
347 if (numReceived < 1)
348 break;
349 availableBufferSpace -= numReceived;
350 receivedSoFar += numReceived;
351 } else {
352 break;
353 }
354 }
355 *np -= availableBufferSpace;
356
357#ifdef SERIAL_CAN_DEBUG
358 efiPrintf("* ret: %d %d (%d)", i, *np, availableBufferSpace);
359 for (int j = 0; j < receivedSoFar; j++) {
360 efiPrintf("* [%d]: %02x", j, rxbuf[j]);
361 }
362#endif /* SERIAL_CAN_DEBUG */
363
364 return CAN_MSG_OK;
365}
366
367int IsoTpRx::readTimeout(uint8_t *rxbuf, size_t *size, sysinterval_t timeout)
368{
369 //is fxbuf is too small?
370 bool overflow = false;
371 bool isFirstFrame = true;
372 size_t availableAtBuffer = *size;
373 uint8_t *buf = rxbuf;
374
375 do {
376 CANRxFrame rxmsg;
377
378 // TODO: adjust timeout!
379 if (!rxFifoBuf.get(rxmsg, timeout)) {
380 // TODO: error codes
381 if (isFirstFrame) {
382 // this is not an error
383 //efiPrintf("IsoTp: rx timeout, nothing received");
384 *size = 0;
385 return 0;
386 }
387
388 efiPrintf("IsoTP: rx timeout, %d left to receive", waitingForNumBytes);
389 *size = buf - rxbuf;
390 return -1;
391 }
392
393 uint8_t frameType = (rxmsg.data8[isoHeaderByteIndex] >> 4) & 0xf;
395 efiPrintf("receiveFrame frameType=%d", frameType);
396 #if EFI_PROD_CODE
397 printCANRxFrame(-1, rxmsg);
398 #endif // EFI_PROD_CODE
399 }
400 size_t numBytesAvailable;
401 uint8_t frameIdx;
402 const uint8_t *srcBuf;
403 switch (frameType) {
405 // TODO: check that this is first packet! see isFirstFrame
406 numBytesAvailable = rxmsg.data8[isoHeaderByteIndex] & 0xf;
407 waitingForNumBytes = numBytesAvailable;
408 srcBuf = rxmsg.data8 + 1 + isoHeaderByteIndex;
409 break;
411 // TODO: check that this is first packet! see isFirstFrame
412 waitingForNumBytes = ((rxmsg.data8[isoHeaderByteIndex] & 0xf) << 8) | rxmsg.data8[isoHeaderByteIndex + 1];
414 numBytesAvailable = minI(waitingForNumBytes, 6 - isoHeaderByteIndex);
415 srcBuf = rxmsg.data8 + 2 + isoHeaderByteIndex;
416// rxTransport->onTpFirstFrame(); // used to send flow control message
417 break;
419 frameIdx = rxmsg.data8[isoHeaderByteIndex] & 0xf;
420 if (waitingForNumBytes < 0) {
421 // Should not happen
422 return -4;
423 }
424 if (waitingForFrameIndex != frameIdx) {
425 // todo: that's an abnormal situation, and we probably should react?
426 // TODO: error codes
427 efiPrintf("received frame index %d is not what expected %d",
428 frameIdx, waitingForFrameIndex);
429 return -2;
430 }
431 numBytesAvailable = minI(waitingForNumBytes, 7 - isoHeaderByteIndex);
432 srcBuf = rxmsg.data8 + 1 + isoHeaderByteIndex;
434 break;
436 // todo: currently we just ignore the FC frame
437 // TODO: we should not receive FC frame while receiving data
438 break;
439 default:
440 // bad frame type
441 // TODO: error codes
442 return -3;
443 }
444
445 if (isFirstFrame) {
446 if ((buf) && (waitingForNumBytes > availableAtBuffer)) {
447 efiPrintf("receive buffer is not enough %d > %d", waitingForNumBytes, availableAtBuffer);
448 }
449 isFirstFrame = false;
450 }
451
452 if (buf != nullptr) {
453 int numBytesToCopy = minI(availableAtBuffer, numBytesAvailable);
454
455 memcpy(buf, srcBuf, numBytesToCopy);
456 buf += numBytesToCopy;
457 availableAtBuffer -= numBytesToCopy;
458
459 // if there are some more bytes left, receive and drop
460 if (numBytesAvailable > numBytesToCopy) {
461 overflow = true;
462 }
463 }
464
465 // according to the specs, we need to acknowledge the received multi-frame start frame
466 if (frameType == ISO_TP_FRAME_FIRST) {
467 sendFlowControl(timeout);
468 }
469
470 waitingForNumBytes -= numBytesAvailable;
471 } while (waitingForNumBytes > 0);
472
473 // received size
474 *size = buf - rxbuf;
475
476 return overflow ? 1 : 0;
477}
478
480#if EFI_PROD_CODE || SIMULATOR
481 CANRxFrame rxmsg;
482
483 while (rxFifoBuf.get(rxmsg, 0)) {
485 }
486#endif
487
490}
491
492int IsoTpRxTx::writeTimeout(const uint8_t *txbuf, size_t size, sysinterval_t timeout) {
493 int offset = 0;
494
496 PRINT("*** INFO: sendDataTimeout %d" PRINT_EOL, size);
497 }
498
499 if (size < 1)
500 return 0;
501
502 // 1 frame
503 if (size <= 7 - isoHeaderByteIndex) {
504 IsoTpFrameHeader header;
506 header.numBytes = size;
507 return IsoTpBase::sendFrame(header, txbuf, size, timeout);
508 }
509
510 // multiple frames
511
512 // send the first header frame (FF)
513 IsoTpFrameHeader header;
515 header.numBytes = size;
516 int numSent = IsoTpBase::sendFrame(header, txbuf + offset, size, timeout);
517 offset += numSent;
518 size -= numSent;
519
520 // get a flow control (FC) frame
521#if !EFI_UNIT_TEST // todo: add FC to unit-tests?
522 CANRxFrame rxmsg;
523 size_t numFcReceived = 0;
524 int separationTimeUs = 0;
525 while (numFcReceived < 3) {
526 // TODO: adjust timeout!
527 if (!rxFifoBuf.get(rxmsg, timeout)) {
528 efiPrintf("IsoTp: Flow Control frame not received");
529 //warning(ObdCode::CUSTOM_ERR_CAN_COMMUNICATION, "CAN Flow Control frame not received");
530 return 0;
531 }
532 uint8_t frameType = (rxmsg.data8[isoHeaderByteIndex] >> 4) & 0xf;
533
534 // if something is not ok
535 if (frameType != ISO_TP_FRAME_FLOW_CONTROL) {
536 // should we expect only FC here?
537 continue;
538 }
539
540 // Ok, frame is FC
541 numFcReceived++;
542 uint8_t flowStatus = rxmsg.data8[isoHeaderByteIndex] & 0xf;
543
544 if (flowStatus == CAN_FLOW_STATUS_ABORT) {
545 efiPrintf("IsoTp: Flow Control ABORT");
546 // TODO: error codes
547 return -4;
548 }
549
550 if (flowStatus == CAN_FLOW_STATUS_WAIT_MORE) {
551 // if the receiver is not ready yet and asks to wait for the next FC frame (give it 3 attempts)
552 if (numFcReceived < 3) {
553 continue;
554 }
555 // TODO: error codes
556 return -5;
557 }
558
559 if (flowStatus != CAN_FLOW_STATUS_OK) {
560 efiPrintf("IsoTp: Flow Control unknown Status %d", flowStatus);
561 // TODO: error codes
562 return -6;
563 }
564
565 uint8_t blockSize = rxmsg.data8[isoHeaderByteIndex + 1];
566 uint8_t minSeparationTime = rxmsg.data8[isoHeaderByteIndex + 2];
567 if (blockSize != 0) {
568 // todo: process other Flow Control fields (see ISO 15765-2)
569 efiPrintf("IsoTp: Flow Control blockSize is not supported %d", blockSize);
570 // TODO: error codes
571 return -7;
572 }
573
574 if (minSeparationTime <= 0x7f) {
575 // mS units
576 separationTimeUs = minSeparationTime * 1000;
577 } else if ((minSeparationTime >= 0xf1) && (minSeparationTime <= 0xf9)) {
578 // 100 uS units
579 separationTimeUs = (minSeparationTime - 0xf0) * 100;
580 }
581
582 break;
583 }
584#endif /* EFI_UNIT_TEST */
585
586 // send the rest of the data
587 uint8_t idx = 1;
588 while (size > 0) {
589 int len = minI(size, 7 - isoHeaderByteIndex);
590 // send the consecutive frames
592 header.index = ((idx++) & 0x0f);
593 header.numBytes = len;
594 numSent = IsoTpBase::sendFrame(header, txbuf + offset, len, timeout);
595 if (numSent < 1)
596 break;
597 offset += numSent;
598 size -= numSent;
599
600#if ! EFI_UNIT_TEST
601 if (separationTimeUs) {
602 chThdSleepMicroseconds(separationTimeUs);
603 }
604#endif // EFI_UNIT_TEST
605 }
606 return offset;
607}
608
609#endif // HAL_USE_CAN || EFI_UNIT_TEST
int32_t can_msg_t
Definition can_mocks.h:6
int32_t can_sysinterval_t
Definition can_mocks.h:7
void printCANRxFrame(const size_t busIndex, const CANRxFrame &rx)
Definition can_rx.cpp:29
fifo_buffer< uint8_t, CAN_FIFO_BUF_SIZE > txFifoBuf
Definition isotp.h:139
fifo_buffer< uint8_t, CAN_FIFO_BUF_SIZE > rxFifoBuf
Definition isotp.h:138
can_msg_t streamFlushTx(can_sysinterval_t timeout)
Definition isotp.cpp:325
int sendDataTimeout(const uint8_t *txbuf, int numBytes, can_sysinterval_t timeout)
Definition isotp.cpp:188
int receiveFrame(const CANRxFrame &rxmsg, uint8_t *buf, int num, can_sysinterval_t timeout)
Definition isotp.cpp:90
ICanReceiver * rxTransport
Definition isotp.h:151
can_msg_t streamReceiveTimeout(size_t *np, uint8_t *rxbuf, can_sysinterval_t timeout)
Definition isotp.cpp:335
int waitingForNumBytes
Definition isotp.h:148
bool isComplete
Definition isotp.h:160
int waitingForFrameIndex
Definition isotp.h:149
int getDataFromFifo(uint8_t *rxbuf, size_t &numBytes)
Definition isotp.cpp:272
can_msg_t streamAddToTxTimeout(size_t *np, const uint8_t *txbuf, can_sysinterval_t timeout)
Definition isotp.cpp:285
bool pauseCANdueToSerial
Definition engine.h:127
virtual can_msg_t receive(CANRxFrame *crfp, can_sysinterval_t timeout)=0
virtual void onTpFirstFrame()=0
size_t busIndex
Definition isotp.h:118
can_msg_t transmit(CanTxMessage &ctfp, can_sysinterval_t timeout)
Definition isotp.h:101
uint32_t txFrameId
Definition isotp.h:120
int sendFrame(const IsoTpFrameHeader &header, const uint8_t *data, int num, can_sysinterval_t timeout)
Definition isotp.cpp:14
void sendFlowControl(can_sysinterval_t timeout)
Definition isotp.cpp:80
size_t isoHeaderByteIndex
Definition isotp.h:114
IsoTpFrameType frameType
Definition isotp.h:38
int separationTime
Definition isotp.h:47
int readTimeout(uint8_t *rxbuf, size_t *size, sysinterval_t timeout)
Definition isotp.cpp:367
int waitingForNumBytes
Definition isotp.h:231
void resetRxVerbose()
Definition isotp.cpp:479
uint8_t waitingForFrameIndex
Definition isotp.h:232
fifo_buffer_sync< CANRxFrame, ISOTP_RX_QUEUE_LEN > rxFifoBuf
Definition isotp.h:235
int writeTimeout(const uint8_t *txbuf, size_t size, sysinterval_t timeout)
Definition isotp.cpp:492
static EngineAccessor engine
Definition engine.h:421
static constexpr engine_configuration_s * engineConfiguration
static const size_t maxDlc
Definition isotp.cpp:12
@ ISO_TP_FRAME_CONSECUTIVE
Definition isotp.h:32
@ ISO_TP_FRAME_FIRST
Definition isotp.h:31
@ ISO_TP_FRAME_FLOW_CONTROL
Definition isotp.h:33
@ ISO_TP_FRAME_SINGLE
Definition isotp.h:30
uint8_t data8[8]
Frame data.
Definition can_mocks.h:55
uint8_t DLC
Data length.
Definition can_mocks.h:42
composite packet size
uint16_t offset
Definition tunerstudio.h:0