GCC Code Coverage Report


Directory: ./
File: firmware/controllers/can/isotp/isotp.h
Date: 2025-11-16 14:52:24
Coverage Exec Excl Total
Lines: 50.0% 7 0 14
Functions: 25.0% 1 0 4
Branches: -% 0 0 0
Decisions: -% 0 - 0

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 class ICanTransmitter {
75 public:
76 virtual can_msg_t transmit(CanTxMessage &ctfp, can_sysinterval_t timeout) = 0;
77 };
78
79 class ICanReceiver {
80 public:
81 virtual can_msg_t receive(CANRxFrame *crfp, can_sysinterval_t timeout) = 0;
82 virtual void onTpFirstFrame() = 0;
83 };
84
85 // We need an abstraction layer for unit-testing
86 // todo: no reason for composite entity to exist, keep splitting CanStreamerState into RX and TX!
87 class ICanTransport : public ICanTransmitter, public ICanReceiver {
88 };
89
90 // most efficient sizes are 6 + x * 7 that way whole buffer is transmitted as (x+1) full packets
91 #ifndef CAN_FIFO_BUF_SIZE
92 #define CAN_FIFO_BUF_SIZE 76
93 #endif // CAN_FIFO_BUF_SIZE
94
95 #define CAN_FIFO_FRAME_SIZE 8
96
97 class CanStreamerState {
98 public:
99 // serial_can uses fifo_buffer_sync, unify?
100 fifo_buffer<uint8_t, CAN_FIFO_BUF_SIZE> rxFifoBuf;
101 fifo_buffer<uint8_t, CAN_FIFO_BUF_SIZE> txFifoBuf;
102
103 /*
104 #if defined(TS_CAN_DEVICE_SHORT_PACKETS_IN_ONE_FRAME)
105 // used to restore the original packet with CRC
106 uint8_t shortCrcPacketStagingArea[13];
107 #endif
108 */
109
110 // Offset of first ISO-TP byte, usually 0
111 // but some vendors add some specific data in first CAN byte
112 size_t isoHeaderByteIndex = 0;
113
114 // used for multi-frame ISO-TP packets
115 int waitingForNumBytes = 0;
116 int waitingForFrameIndex = 0;
117
118 ICanTransmitter *txTransport;
119 ICanReceiver *rxTransport;
120
121 int busIndex;
122 int txFrameId;
123
124 public:
125 13 CanStreamerState(ICanTransmitter *p_txTransport, ICanReceiver *p_rxTransport, int p_busIndex, int p_txFrameId)
126 13 :
127 13 txTransport(p_txTransport),
128 13 rxTransport(p_rxTransport),
129 13 busIndex(p_busIndex),
130 13 txFrameId(p_txFrameId)
131 13 {}
132
133 bool isComplete{};
134
135 void reset();
136
137 int sendFrame(const IsoTpFrameHeader & header, const uint8_t *data, int num, can_sysinterval_t timeout);
138 int receiveFrame(const CANRxFrame &rxmsg, uint8_t *buf, int num, can_sysinterval_t timeout);
139 int getDataFromFifo(uint8_t *rxbuf, size_t &numBytes);
140 // returns the number of bytes sent
141 int sendDataTimeout(const uint8_t *txbuf, int numBytes, can_sysinterval_t timeout);
142
143 // streaming support for TS I/O (see tunerstudio_io.cpp)
144 can_msg_t streamAddToTxTimeout(size_t *np, const uint8_t *txbuf, can_sysinterval_t timeout);
145 can_msg_t streamFlushTx(can_sysinterval_t timeout);
146 can_msg_t streamReceiveTimeout(size_t *np, uint8_t *rxbuf, can_sysinterval_t timeout);
147 };
148