1// Copyright (C) 2017 The Qt Company Ltd.
2// Copyright (C) 2021 Andre Hartmann <aha_1980@gmx.de>
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QCANBUSDEVICE_H
6#define QCANBUSDEVICE_H
7
8#include <QtCore/qobject.h>
9#include <QtSerialBus/qcanbusframe.h>
10#include <QtSerialBus/qcanbusdeviceinfo.h>
11
12#include <functional>
13
14QT_BEGIN_NAMESPACE
15
16class QCanBusDevicePrivate;
17
18class Q_SERIALBUS_EXPORT QCanBusDevice : public QObject
19{
20 Q_OBJECT
21 Q_DECLARE_PRIVATE(QCanBusDevice)
22 Q_DISABLE_COPY(QCanBusDevice)
23
24public:
25 enum CanBusError {
26 NoError,
27 ReadError,
28 WriteError,
29 ConnectionError,
30 ConfigurationError,
31 UnknownError,
32 OperationError,
33 TimeoutError
34 };
35 Q_ENUM(CanBusError)
36
37 enum CanBusDeviceState {
38 UnconnectedState,
39 ConnectingState,
40 ConnectedState,
41 ClosingState
42 };
43 Q_ENUM(CanBusDeviceState)
44
45 enum class CanBusStatus {
46 Unknown,
47 Good,
48 Warning,
49 Error,
50 BusOff
51 };
52 Q_ENUM(CanBusStatus)
53
54 enum ConfigurationKey {
55 RawFilterKey = 0,
56 ErrorFilterKey,
57 LoopbackKey,
58 ReceiveOwnKey,
59 BitRateKey,
60 CanFdKey,
61 DataBitRateKey,
62 ProtocolKey,
63 UserKey = 30
64 };
65 Q_ENUM(ConfigurationKey)
66
67 struct Filter
68 {
69 friend constexpr bool operator==(const Filter &a, const Filter &b) noexcept
70 {
71 return a.frameId == b.frameId && a.frameIdMask == b.frameIdMask
72 && a.type == b.type && a.format == b.format;
73 }
74
75 friend constexpr bool operator!=(const Filter &a, const Filter &b) noexcept
76 {
77 return !operator==(a, b);
78 }
79
80 enum FormatFilter {
81 MatchBaseFormat = 0x0001,
82 MatchExtendedFormat = 0x0002,
83 MatchBaseAndExtendedFormat = 0x0003,
84 };
85 Q_DECLARE_FLAGS(FormatFilters, FormatFilter)
86
87 QCanBusFrame::FrameId frameId = 0;
88 QCanBusFrame::FrameId frameIdMask = 0;
89 QCanBusFrame::FrameType type = QCanBusFrame::InvalidFrame;
90 FormatFilter format = MatchBaseAndExtendedFormat;
91 };
92
93 explicit QCanBusDevice(QObject *parent = nullptr);
94
95 virtual void setConfigurationParameter(ConfigurationKey key, const QVariant &value);
96 QVariant configurationParameter(ConfigurationKey key) const;
97 QList<ConfigurationKey> configurationKeys() const;
98
99 virtual bool writeFrame(const QCanBusFrame &frame) = 0;
100 QCanBusFrame readFrame();
101 QList<QCanBusFrame> readAllFrames();
102 qint64 framesAvailable() const;
103 qint64 framesToWrite() const;
104
105 virtual void resetController();
106 virtual bool hasBusStatus() const;
107 virtual CanBusStatus busStatus();
108
109 enum Direction {
110 Input = 1,
111 Output = 2,
112 AllDirections = Input | Output
113 };
114 Q_DECLARE_FLAGS(Directions, Direction)
115 void clear(Directions direction = Direction::AllDirections);
116
117 virtual bool waitForFramesWritten(int msecs);
118 virtual bool waitForFramesReceived(int msecs);
119
120 bool connectDevice();
121 void disconnectDevice();
122
123 CanBusDeviceState state() const;
124
125 CanBusError error() const;
126 QString errorString() const;
127
128 virtual QString interpretErrorFrame(const QCanBusFrame &errorFrame) = 0;
129 virtual QCanBusDeviceInfo deviceInfo() const;
130
131Q_SIGNALS:
132 void errorOccurred(QCanBusDevice::CanBusError);
133 void framesReceived();
134 void framesWritten(qint64 framesCount);
135 void stateChanged(QCanBusDevice::CanBusDeviceState state);
136
137protected:
138 void setState(QCanBusDevice::CanBusDeviceState newState);
139 void setError(const QString &errorText, QCanBusDevice::CanBusError);
140 void clearError();
141
142 void enqueueReceivedFrames(const QList<QCanBusFrame> &newFrames);
143
144 void enqueueOutgoingFrame(const QCanBusFrame &newFrame);
145 QCanBusFrame dequeueOutgoingFrame();
146 bool hasOutgoingFrames() const;
147
148 virtual bool open() = 0;
149 virtual void close() = 0;
150
151 static QCanBusDeviceInfo createDeviceInfo(const QString &plugin,
152 const QString &name,
153 bool isVirtual,
154 bool isFlexibleDataRateCapable);
155 static QCanBusDeviceInfo createDeviceInfo(const QString &plugin,
156 const QString &name,
157 const QString &serialNumber,
158 const QString &description,
159 const QString &alias,
160 int channel,
161 bool isVirtual,
162 bool isFlexibleDataRateCapable);
163};
164
165Q_DECLARE_TYPEINFO(QCanBusDevice::CanBusError, Q_PRIMITIVE_TYPE);
166Q_DECLARE_TYPEINFO(QCanBusDevice::CanBusDeviceState, Q_PRIMITIVE_TYPE);
167Q_DECLARE_TYPEINFO(QCanBusDevice::ConfigurationKey, Q_PRIMITIVE_TYPE);
168Q_DECLARE_TYPEINFO(QCanBusDevice::Filter, Q_PRIMITIVE_TYPE);
169Q_DECLARE_TYPEINFO(QCanBusDevice::Filter::FormatFilter, Q_PRIMITIVE_TYPE);
170
171Q_DECLARE_OPERATORS_FOR_FLAGS(QCanBusDevice::Filter::FormatFilters)
172Q_DECLARE_OPERATORS_FOR_FLAGS(QCanBusDevice::Directions)
173
174QT_END_NAMESPACE
175
176Q_DECLARE_METATYPE(QCanBusDevice::Filter::FormatFilter)
177Q_DECLARE_METATYPE(QList<QCanBusDevice::Filter>)
178
179#endif // QCANBUSDEVICE_H
180

source code of qtserialbus/src/serialbus/qcanbusdevice.h