rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Public Member Functions | Protected Attributes | Private Attributes
IsoTpRx Class Reference

#include <isotp.h>

Inheritance diagram for IsoTpRx:
Inheritance graph
[legend]
Collaboration diagram for IsoTpRx:
Collaboration graph
[legend]

Public Member Functions

 IsoTpRx (size_t p_busIndex, uint32_t p_rxFrameId, uint32_t p_txFrameId)
 
 ~IsoTpRx ()
 
void reset ()
 
virtual void decodeFrame (const CANRxFrame &frame, efitick_t nowNt)
 
int readTimeout (uint8_t *rxbuf, size_t *size, sysinterval_t timeout)
 
- Public Member Functions inherited from CanListener
 CanListener (uint32_t id)
 
CanListenerprocessFrame (const size_t busIndex, const CANRxFrame &frame, efitick_t nowNt)
 
uint32_t getId ()
 
void setNext (CanListener *next)
 
virtual CanListenerrequest ()
 
CanListenergetNext () const
 
virtual bool acceptFrame (const size_t busIndex, const CANRxFrame &frame) const
 
- Public Member Functions inherited from IsoTpBase
 IsoTpBase (ICanTransmitter *p_txTransport, size_t p_busIndex, uint32_t p_rxFrameId, uint32_t p_txFrameId)
 
int sendFrame (const IsoTpFrameHeader &header, const uint8_t *data, int num, can_sysinterval_t timeout)
 
can_msg_t transmit (CanTxMessage &ctfp, can_sysinterval_t timeout)
 

Protected Attributes

fifo_buffer_sync< CANRxFrame, ISOTP_RX_QUEUE_LEN > rxFifoBuf
 

Private Attributes

int waitingForNumBytes = 0
 
uint8_t waitingForFrameIndex = 0
 

Additional Inherited Members

- Data Fields inherited from IsoTpBase
size_t isoHeaderByteIndex = 0
 
ICanTransmittertxTransport
 
size_t busIndex
 
uint32_t rxFrameId
 
uint32_t txFrameId
 

Detailed Description

Definition at line 176 of file isotp.h.

Constructor & Destructor Documentation

◆ IsoTpRx()

IsoTpRx::IsoTpRx ( size_t  p_busIndex,
uint32_t  p_rxFrameId,
uint32_t  p_txFrameId 
)
inline

Definition at line 178 of file isotp.h.

179 :
180 CanListener(p_rxFrameId),
181 IsoTpBase(nullptr, p_busIndex, p_rxFrameId, p_txFrameId)
182 {
183 rxFifoBuf.clear();
184 registerCanListener(*this);
185 }
void registerCanListener(CanListener &listener)
Definition can_rx.cpp:86
fifo_buffer_sync< CANRxFrame, ISOTP_RX_QUEUE_LEN > rxFifoBuf
Definition isotp.h:225
Here is the call graph for this function:

◆ ~IsoTpRx()

IsoTpRx::~IsoTpRx ( )
inline

Definition at line 187 of file isotp.h.

187 {
189 }
void unregisterCanListener(CanListener &listener)
Definition can_rx.cpp:96
Here is the call graph for this function:

Member Function Documentation

◆ decodeFrame()

virtual void IsoTpRx::decodeFrame ( const CANRxFrame frame,
efitick_t  nowNt 
)
inlinevirtual

Implements CanListener.

Definition at line 198 of file isotp.h.

199 {
200 if (frame.DLC < 1 + isoHeaderByteIndex) {
201 // invalid++;
202 return;
203 }
204
205 if (isoHeaderByteIndex) {
206 if (frame.data8[0] != (txFrameId & 0xff)) {
207 return;
208 }
209 }
210
211 if (!rxFifoBuf.put(frame)) {
212 // overruns++;
213 }
214 }
uint32_t txFrameId
Definition isotp.h:118
size_t isoHeaderByteIndex
Definition isotp.h:112
uint8_t data8[8]
Frame data.
Definition can_mocks.h:55
uint8_t DLC
Data length.
Definition can_mocks.h:42

◆ readTimeout()

int IsoTpRx::readTimeout ( uint8_t *  rxbuf,
size_t size,
sysinterval_t  timeout 
)

Definition at line 348 of file isotp.cpp.

349{
350 //is fxbuf is too small?
351 bool overflow = false;
352 bool isFirstFrame = true;
353 size_t availableAtBuffer = *size;
354 uint8_t *buf = rxbuf;
355
356 do {
357 CANRxFrame rxmsg;
358
359 // TODO: adjust timeout!
360 if (!rxFifoBuf.get(rxmsg, timeout)) {
361 // TODO: error codes
362 if (isFirstFrame) {
363 efiPrintf("IsoTp: rx timeout, nothing received");
364 } else {
365 efiPrintf("IsoTP: rx timeout, %d left to receive", waitingForNumBytes);
366 }
367 return -1;
368 }
369
370 uint8_t frameType = (rxmsg.data8[isoHeaderByteIndex] >> 4) & 0xf;
372 efiPrintf("receiveFrame frameType=%d", frameType);
373 #if EFI_PROD_CODE
374 printCANRxFrame(-1, rxmsg);
375 #endif // EFI_PROD_CODE
376 }
377 size_t numBytesAvailable;
378 uint8_t frameIdx;
379 const uint8_t *srcBuf;
380 switch (frameType) {
382 // TODO: check that this is first packet! see isFirstFrame
383 numBytesAvailable = rxmsg.data8[isoHeaderByteIndex] & 0xf;
384 waitingForNumBytes = numBytesAvailable;
385 srcBuf = rxmsg.data8 + 1 + isoHeaderByteIndex;
386 break;
388 // TODO: check that this is first packet! see isFirstFrame
389 waitingForNumBytes = ((rxmsg.data8[isoHeaderByteIndex] & 0xf) << 8) | rxmsg.data8[isoHeaderByteIndex + 1];
391 numBytesAvailable = minI(waitingForNumBytes, 6 - isoHeaderByteIndex);
392 srcBuf = rxmsg.data8 + 2 + isoHeaderByteIndex;
393// rxTransport->onTpFirstFrame(); // used to send flow control message
394 break;
396 frameIdx = rxmsg.data8[isoHeaderByteIndex] & 0xf;
397 if (waitingForNumBytes < 0 || waitingForFrameIndex != frameIdx) {
398 // todo: that's an abnormal situation, and we probably should react?
399 // TODO: error codes
400 return -2;
401 }
402 numBytesAvailable = minI(waitingForNumBytes, 7 - isoHeaderByteIndex);
403 srcBuf = rxmsg.data8 + 1 + isoHeaderByteIndex;
405 break;
407 // todo: currently we just ignore the FC frame
408 // TODO: we should not receive FC frame while receiving data
409 break;
410 default:
411 // bad frame type
412 // TODO: error codes
413 return -3;
414 }
415
416 if (isFirstFrame) {
417 if ((buf) && (waitingForNumBytes > availableAtBuffer)) {
418 efiPrintf("receive buffer is not enough %d > %d", waitingForNumBytes, availableAtBuffer);
419 }
420 isFirstFrame = false;
421 }
422
423 if (buf != nullptr) {
424 int numBytesToCopy = minI(availableAtBuffer, numBytesAvailable);
425
426 memcpy(buf, srcBuf, numBytesToCopy);
427 buf += numBytesToCopy;
428 availableAtBuffer -= numBytesToCopy;
429
430 // if there are some more bytes left, receive and drop
431 if (numBytesAvailable > numBytesToCopy) {
432 overflow = true;
433 }
434 }
435
436 // according to the specs, we need to acknowledge the received multi-frame start frame
437 if (frameType == ISO_TP_FRAME_FIRST) {
438 IsoTpFrameHeader header;
440 header.fcFlag = 0; // = "continue to send"
441 header.blockSize = 0; // = the remaining "frames" to be sent without flow control or delay
442 header.separationTime = 0; // = wait 0 milliseconds, send immediately
443 sendFrame(header, nullptr, 0, timeout);
444 }
445
446 waitingForNumBytes -= numBytesAvailable;
447 } while (waitingForNumBytes > 0);
448
449 // received size
450 *size = buf - rxbuf;
451
452 return overflow ? 1 : 0;
453}
void printCANRxFrame(const size_t busIndex, const CANRxFrame &rx)
Definition can_rx.cpp:29
int sendFrame(const IsoTpFrameHeader &header, const uint8_t *data, int num, can_sysinterval_t timeout)
Definition isotp.cpp:12
IsoTpFrameType frameType
Definition isotp.h:38
int separationTime
Definition isotp.h:47
int waitingForNumBytes
Definition isotp.h:221
uint8_t waitingForFrameIndex
Definition isotp.h:222
static constexpr engine_configuration_s * engineConfiguration
@ 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
composite packet size
Here is the call graph for this function:

◆ reset()

void IsoTpRx::reset ( )
inline

Definition at line 191 of file isotp.h.

191 {
192 rxFifoBuf.clear();
195 }

Field Documentation

◆ rxFifoBuf

fifo_buffer_sync<CANRxFrame, ISOTP_RX_QUEUE_LEN> IsoTpRx::rxFifoBuf
protected

Definition at line 225 of file isotp.h.

Referenced by decodeFrame(), IsoTpRx(), readTimeout(), reset(), and IsoTpRxTx::writeTimeout().

◆ waitingForFrameIndex

uint8_t IsoTpRx::waitingForFrameIndex = 0
private

Definition at line 222 of file isotp.h.

Referenced by readTimeout(), and reset().

◆ waitingForNumBytes

int IsoTpRx::waitingForNumBytes = 0
private

Definition at line 221 of file isotp.h.

Referenced by readTimeout(), and reset().


The documentation for this class was generated from the following files: