1/****************************************************************************
2**
3** Copyright (C) 2017 Ford Motor Company.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the QtSerialBus module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#ifndef PASSTHRUCAN_J2534PASSTHRU_H
38#define PASSTHRUCAN_J2534PASSTHRU_H
39
40#include <QByteArray>
41#include <QLibrary>
42#include <QLoggingCategory>
43#include <QObject>
44#include <QString>
45
46#ifdef Q_OS_WIN32
47# define J2534_API __stdcall
48#else
49# define J2534_API
50#endif
51
52Q_DECLARE_LOGGING_CATEGORY(QT_CANBUS_PLUGINS_PASSTHRU)
53
54namespace J2534 {
55
56class Message;
57
58extern "C" {
59
60typedef long (J2534_API *PassThruOpenFunc)(const void *pName, ulong *pDeviceId);
61typedef long (J2534_API *PassThruCloseFunc)(ulong deviceId);
62typedef long (J2534_API *PassThruConnectFunc)(ulong deviceId, ulong protocolId, ulong flags,
63 ulong baudRate, ulong *pChannelId);
64typedef long (J2534_API *PassThruDisconnectFunc)(ulong channelId);
65typedef long (J2534_API *PassThruReadMsgsFunc)(ulong channelId, Message *pMsg,
66 ulong *pNumMsgs, ulong timeout);
67typedef long (J2534_API *PassThruWriteMsgsFunc)(ulong channelId, const Message *pMsg,
68 ulong *pNumMsgs, ulong timeout);
69typedef long (J2534_API *PassThruStartMsgFilterFunc)(ulong channelID, ulong filterType,
70 const Message *pMaskMsg,
71 const Message *pPatternMsg,
72 const Message *pFlowControlMsg,
73 ulong *pFilterId);
74typedef long (J2534_API *PassThruGetLastErrorFunc)(char *pErrorDescription);
75typedef long (J2534_API *PassThruIoctlFunc)(ulong channelId, ulong ioctlId,
76 const void *pInput, void *pOutput);
77} // extern "C"
78
79enum class Protocol : uint {
80 J1850VPW = 1,
81 J1850PWM,
82 ISO9141,
83 ISO14230,
84 CAN,
85 ISO15765,
86 SCIAEngine,
87 SCIATrans,
88 SCIBEngine,
89 SCIBTrans
90};
91
92class Message
93{
94public:
95 static const ulong maxSize = 4128;
96
97 enum RxStatusBit {
98 InTxMsgType = 1 << 0,
99 InStartOfMessage = 1 << 1,
100 InRxBreak = 1 << 2,
101 InTxIndication = 1 << 3,
102 InISO15765PaddingError = 1 << 4,
103 InISO15765AddrType = 1 << 7,
104 InCAN29BitID = 1 << 8
105 };
106 Q_DECLARE_FLAGS(RxStatus, RxStatusBit)
107
108 enum TxFlag {
109 OutISO15765FramePad = 1 << 6,
110 OutISO15765AddrType = 1 << 7,
111 OutCAN29BitID = 1 << 8,
112 OutWaitP3MinOnly = 1 << 9
113 };
114 Q_DECLARE_FLAGS(TxFlags, TxFlag)
115
116 Message();
117 explicit Message(Protocol proto);
118
119 Protocol protocolId() const { return Protocol(m_protocolId); }
120 void setProtocolId(Protocol proto) { m_protocolId = uint(proto); }
121
122 RxStatus rxStatus() const { return RxStatus(uint(m_rxStatus)); }
123 void setRxStatus(RxStatus status) { m_rxStatus = uint(status); }
124
125 TxFlags txFlags() const { return TxFlags(uint(m_txFlags)); }
126 void setTxFlags(TxFlags flags) { m_txFlags = uint(flags); }
127
128 ulong timestamp() const { return m_timestamp; }
129 void setTimestamp(ulong stamp) { m_timestamp = stamp; }
130
131 ulong size() const { return m_dataSize; }
132 void setSize(ulong dataSize) { m_dataSize = dataSize; }
133
134 ulong extraDataIndex() const { return m_extraDataIndex; }
135 void setExtraDataIndex(ulong index) { m_extraDataIndex = index; }
136
137 char *data() { return m_data; }
138 const char *data() const { return m_data; }
139
140private:
141 ulong m_protocolId = 0;
142 ulong m_rxStatus = 0;
143 ulong m_txFlags = 0;
144 ulong m_timestamp = 0;
145 ulong m_dataSize = 0;
146 ulong m_extraDataIndex = 0;
147 char m_data[maxSize];
148};
149
150Q_DECLARE_OPERATORS_FOR_FLAGS(Message::RxStatus)
151Q_DECLARE_OPERATORS_FOR_FLAGS(Message::TxFlags)
152
153class Config
154{
155public:
156 enum Parameter {
157 DataRate = 1,
158
159 Loopback = 3,
160 NodeAddress,
161 NetworkLine,
162 P1Min,
163 P1Max,
164 P2Min,
165 P2Max,
166 P3Min,
167 P3Max,
168 P4Min,
169 P4Max,
170 W1,
171 W2,
172 W3,
173 W4,
174 W5,
175 Tidle,
176 Tinil,
177 Twup,
178 Parity,
179 BitSamplePoint,
180 SyncJumpWidth,
181 W0,
182 T1Max,
183 T2Max,
184 T4Max,
185 T5Max,
186 ISO15765BS,
187 ISO15765STmin,
188 DataBits,
189 FiveBaudMod,
190 BSTx,
191 STminTx,
192 T3Max,
193 ISO15765WFTMax,
194
195 CanMixedFormat = 0x8000,
196 J1962Pins,
197
198 SWCANHSDataRate = 0x8010,
199 SWCANSpeedchangeEnable,
200 SWCANResSwitch,
201
202 ActiveChannels = 0x8020,
203 SampleRate,
204 SamplesPerReading,
205 ReadingsPerMsg,
206 AveragingMethod,
207 SampleResolution,
208 InputRangeLow,
209 InputRangeHigh
210 };
211
212 Config() : m_parameter(0), m_value(0) {}
213 explicit Config(Parameter param, ulong val = 0) : m_parameter(param), m_value(val) {}
214
215 Parameter parameter() const { return Parameter(m_parameter); }
216 ulong value() const { return m_value; }
217
218private:
219 ulong m_parameter;
220 ulong m_value;
221};
222
223/**
224 * @brief J2534 pass-through interface, version 04.04.
225 * @internal
226 * @see http://www.drewtech.com/support/passthru.html
227 */
228class PassThru : public QObject
229{
230 Q_OBJECT
231 Q_DISABLE_COPY(PassThru)
232public:
233 typedef ulong Handle;
234
235 enum Status {
236 LoadFailed = -1,
237 NoError = 0,
238 NotSupported,
239 InvalidChannelID,
240 InvalidProtocolID,
241 NullParameter,
242 InvalidIoctlValue,
243 InvalidFlags,
244 Failed,
245 DeviceNotConnected,
246 Timeout,
247 InvalidMsg,
248 InvalidTimeInterval,
249 ExceededLimit,
250 InvalidMsgID,
251 DeviceInUse,
252 InvalidIoctlID,
253 BufferEmpty,
254 BufferFull,
255 BufferOverflow,
256 PinInvalid,
257 ChannelInUse,
258 MsgProtocolID,
259 InvalidFilterID,
260 NoFlowControl,
261 NotUnique,
262 InvalidBaudrate,
263 InvalidDeviceID
264 };
265
266 enum ConnectFlag {
267 CAN29BitID = 1 << 8,
268 ISO9141NoChecksum = 1 << 9,
269 CANIDBoth = 1 << 11,
270 ISO9141KLineOnly = 1 << 12
271 };
272 Q_DECLARE_FLAGS(ConnectFlags, ConnectFlag)
273
274 enum FilterType {
275 PassFilter = 1,
276 BlockFilter,
277 FlowControlFilter
278 };
279
280 enum ClearTarget {
281 TxBuffer = 7,
282 RxBuffer,
283 PeriodicMsgs,
284 MsgFilters
285 };
286
287 explicit PassThru(const QString &libraryPath, QObject *parent = nullptr);
288 virtual ~PassThru();
289
290 Status open(const QByteArray &name, Handle *deviceId);
291 Status close(Handle deviceId);
292 Status connect(Handle deviceId, Protocol protocolId, ConnectFlags flags,
293 uint baudRate, Handle *channelId);
294 Status disconnect(Handle channelId);
295 Status readMsgs(Handle channelId, Message *msgs, ulong *numMsgs, uint timeout = 0);
296 Status writeMsgs(Handle channelId, const Message *msgs, ulong *numMsgs, uint timeout = 0);
297 Status startMsgFilter(Handle channelId, FilterType filterType,
298 const Message &maskMsg, const Message &patternMsg);
299 Status setConfig(Handle channelId, const Config *params, ulong numParams = 1);
300 Status clear(Handle channelId, ClearTarget target);
301
302 Status lastError() const { return m_lastError; }
303 QString lastErrorString() const;
304
305private:
306 Status handleResult(long statusCode);
307
308 template <typename Func>
309 Func resolveApiFunction(Func *funcPtr, const char *name) {
310 *funcPtr = reinterpret_cast<Func>(m_libJ2534.resolve(symbol: name));
311 return *funcPtr;
312 }
313
314 QLibrary m_libJ2534;
315 PassThruOpenFunc m_ptOpen = nullptr;
316 PassThruCloseFunc m_ptClose = nullptr;
317 PassThruConnectFunc m_ptConnect = nullptr;
318 PassThruDisconnectFunc m_ptDisconnect = nullptr;
319 PassThruReadMsgsFunc m_ptReadMsgs = nullptr;
320 PassThruWriteMsgsFunc m_ptWriteMsgs = nullptr;
321 PassThruStartMsgFilterFunc m_ptStartMsgFilter = nullptr;
322 PassThruGetLastErrorFunc m_ptGetLastError = nullptr;
323 PassThruIoctlFunc m_ptIoctl = nullptr;
324 QString m_lastErrorString;
325 Status m_lastError = NoError;
326};
327
328Q_DECLARE_OPERATORS_FOR_FLAGS(PassThru::ConnectFlags)
329
330} // namespace J2534
331
332#endif // PASSTHRUCAN_J2534PASSTHRU_H
333

source code of qtserialbus/src/plugins/canbus/passthrucan/j2534passthru.h