| Line | Branch | Decision | Exec | Source |
|---|---|---|---|---|
| 1 | #pragma once | |||
| 2 | ||||
| 3 | #include "fifo_buffer.h" | |||
| 4 | #include "can_msg_tx.h" | |||
| 5 | ||||
| 6 | #if EFI_UNIT_TEST | |||
| 7 | #define PRINT printf | |||
| 8 | #define PRINT_EOL "\n" | |||
| 9 | #else | |||
| 10 | #define PRINT efiPrintf | |||
| 11 | #define PRINT_EOL "" | |||
| 12 | #endif | |||
| 13 | ||||
| 14 | #if EFI_PROD_CODE | EFI_SIMULATOR | |||
| 15 | #define can_msg_t msg_t | |||
| 16 | #define can_sysinterval_t sysinterval_t | |||
| 17 | #define CAN_MSG_OK MSG_OK | |||
| 18 | #define CAN_MSG_TIMEOUT MSG_TIMEOUT | |||
| 19 | #else | |||
| 20 | #include "can_mocks.h" | |||
| 21 | #endif /* EFI_UNIT_TEST */ | |||
| 22 | ||||
| 23 | #define CAN_FLOW_STATUS_OK 0 | |||
| 24 | #define CAN_FLOW_STATUS_WAIT_MORE 1 | |||
| 25 | #define CAN_FLOW_STATUS_ABORT 2 | |||
| 26 | ||||
| 27 | enum IsoTpFrameType { | |||
| 28 | ISO_TP_FRAME_SINGLE = 0, | |||
| 29 | ISO_TP_FRAME_FIRST = 1, | |||
| 30 | ISO_TP_FRAME_CONSECUTIVE = 2, | |||
| 31 | ISO_TP_FRAME_FLOW_CONTROL = 3, | |||
| 32 | }; | |||
| 33 | ||||
| 34 | class IsoTpFrameHeader { | |||
| 35 | public: | |||
| 36 | IsoTpFrameType frameType; | |||
| 37 | ||||
| 38 | // used for 'single' or 'first' frames | |||
| 39 | int numBytes; | |||
| 40 | // used for 'consecutive' frames | |||
| 41 | int index; | |||
| 42 | // used for 'flow control' frames | |||
| 43 | int fcFlag; | |||
| 44 | int blockSize; | |||
| 45 | int separationTime; | |||
| 46 | }; | |||
| 47 | ||||
| 48 | // todo: what's the point of this wrapper/holder class anyway? | |||
| 49 | class CanRxMessage { | |||
| 50 | public: | |||
| 51 | CanRxMessage() {} | |||
| 52 | ||||
| 53 | ✗ | CanRxMessage(const CANRxFrame &f) { | ||
| 54 | ✗ | frame = f; | ||
| 55 | ✗ | } | ||
| 56 | ||||
| 57 | ✗ | CanRxMessage(const CanRxMessage& msg) : frame(msg.frame) {} | ||
| 58 | ||||
| 59 | ✗ | CanRxMessage& operator=(const CanRxMessage& msg) { | ||
| 60 | // full content copy | |||
| 61 | ✗ | frame = msg.frame; | ||
| 62 | ✗ | return *this; | ||
| 63 | } | |||
| 64 | ||||
| 65 | public: | |||
| 66 | CANRxFrame frame; | |||
| 67 | }; | |||
| 68 | ||||
| 69 | class CanRxMessageSource { | |||
| 70 | public: | |||
| 71 | virtual bool get(CanRxMessage &item, int timeout) = 0; | |||
| 72 | }; | |||
| 73 | ||||
| 74 | // We need an abstraction layer for unit-testing | |||
| 75 | class ICanTransport { | |||
| 76 | public: | |||
| 77 | virtual can_msg_t transmit(const CanTxMessage *ctfp, can_sysinterval_t timeout) = 0; | |||
| 78 | virtual can_msg_t receive(CANRxFrame *crfp, can_sysinterval_t timeout) = 0; | |||
| 79 | }; | |||
| 80 | ||||
| 81 | // most efficient sizes are 6 + x * 7 that way whole buffer is transmitted as (x+1) full packets | |||
| 82 | #ifndef CAN_FIFO_BUF_SIZE | |||
| 83 | #define CAN_FIFO_BUF_SIZE 76 | |||
| 84 | #endif // CAN_FIFO_BUF_SIZE | |||
| 85 | ||||
| 86 | #define CAN_FIFO_FRAME_SIZE 8 | |||
| 87 | ||||
| 88 | class CanStreamerState { | |||
| 89 | public: | |||
| 90 | fifo_buffer<uint8_t, CAN_FIFO_BUF_SIZE> rxFifoBuf; | |||
| 91 | fifo_buffer<uint8_t, CAN_FIFO_BUF_SIZE> txFifoBuf; | |||
| 92 | ||||
| 93 | /* | |||
| 94 | #if defined(TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME) | |||
| 95 | // used to restore the original packet with CRC | |||
| 96 | uint8_t shortCrcPacketStagingArea[13]; | |||
| 97 | #endif | |||
| 98 | */ | |||
| 99 | ||||
| 100 | int isoHeaderByteIndex = 0; | |||
| 101 | ||||
| 102 | // used for multi-frame ISO-TP packets | |||
| 103 | int waitingForNumBytes = 0; | |||
| 104 | int waitingForFrameIndex = 0; | |||
| 105 | ||||
| 106 | ICanTransport *transport; | |||
| 107 | ||||
| 108 | int busIndex; | |||
| 109 | int txFrameId; | |||
| 110 | ||||
| 111 | public: | |||
| 112 | 13 | CanStreamerState(ICanTransport *p_transport, int p_busIndex, int p_txFrameId) | ||
| 113 | 13 | : | ||
| 114 | 13 | transport(p_transport), | ||
| 115 | 13 | busIndex(p_busIndex), | ||
| 116 | 13 | txFrameId(p_txFrameId) | ||
| 117 | 13 | {} | ||
| 118 | ||||
| 119 | int sendFrame(const IsoTpFrameHeader & header, const uint8_t *data, int num, can_sysinterval_t timeout); | |||
| 120 | int receiveFrame(CANRxFrame *rxmsg, uint8_t *buf, int num, can_sysinterval_t timeout); | |||
| 121 | int getDataFromFifo(uint8_t *rxbuf, size_t &numBytes); | |||
| 122 | // returns the number of bytes sent | |||
| 123 | int sendDataTimeout(const uint8_t *txbuf, int numBytes, can_sysinterval_t timeout); | |||
| 124 | ||||
| 125 | // streaming support for TS I/O (see tunerstudio_io.cpp) | |||
| 126 | can_msg_t streamAddToTxTimeout(size_t *np, const uint8_t *txbuf, can_sysinterval_t timeout); | |||
| 127 | can_msg_t streamFlushTx(can_sysinterval_t timeout); | |||
| 128 | can_msg_t streamReceiveTimeout(size_t *np, uint8_t *rxbuf, can_sysinterval_t timeout); | |||
| 129 | }; | |||
| 130 |