1 /****************************************************************************
2 **
3 ** Copyright (C) 2017 The Qt Company Ltd.
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 QCANBUSDEVICE_H
38 #define QCANBUSDEVICE_H
39 
40 #include <QtCore/qobject.h>
41 #include <QtSerialBus/qcanbusframe.h>
42 #include <QtSerialBus/qcanbusdeviceinfo.h>
43 
44 #include <functional>
45 
46 QT_BEGIN_NAMESPACE
47 
48 class QCanBusDevicePrivate;
49 
50 class Q_SERIALBUS_EXPORT QCanBusDevice : public QObject
51 {
52     Q_OBJECT
53     Q_DECLARE_PRIVATE(QCanBusDevice)
54     Q_DISABLE_COPY(QCanBusDevice)
55 
56 public:
57     enum CanBusError {
58         NoError,
59         ReadError,
60         WriteError,
61         ConnectionError,
62         ConfigurationError,
63         UnknownError,
64         OperationError,
65         TimeoutError
66     };
67     Q_ENUM(CanBusError)
68 
69     enum CanBusDeviceState {
70         UnconnectedState,
71         ConnectingState,
72         ConnectedState,
73         ClosingState
74     };
75     Q_ENUM(CanBusDeviceState)
76 
77     enum class CanBusStatus {
78         Unknown,
79         Good,
80         Warning,
81         Error,
82         BusOff
83     };
84     Q_ENUM(CanBusStatus)
85 
86     enum ConfigurationKey {
87         RawFilterKey = 0,
88         ErrorFilterKey,
89         LoopbackKey,
90         ReceiveOwnKey,
91         BitRateKey,
92         CanFdKey,
93         DataBitRateKey,
94         ProtocolKey,
95         UserKey = 30
96     };
97     Q_ENUM(ConfigurationKey)
98 
99     struct Filter
100     {
101         friend constexpr bool operator==(const Filter &a, const Filter &b) noexcept
102         {
103             return a.frameId == b.frameId && a.frameIdMask == b.frameIdMask
104                     && a.type == b.type && a.format == b.format;
105         }
106 
107         friend constexpr bool operator!=(const Filter &a, const Filter &b) noexcept
108         {
109             return !operator==(a, b);
110         }
111 
112         enum FormatFilter {
113             MatchBaseFormat = 0x0001,
114             MatchExtendedFormat = 0x0002,
115             MatchBaseAndExtendedFormat = 0x0003,
116         };
117         Q_DECLARE_FLAGS(FormatFilters, FormatFilter)
118 
119         quint32 frameId = 0;
120         quint32 frameIdMask = 0;
121         QCanBusFrame::FrameType type = QCanBusFrame::InvalidFrame;
122         FormatFilter format = MatchBaseAndExtendedFormat;
123     };
124 
125     explicit QCanBusDevice(QObject *parent = nullptr);
126 
127     virtual void setConfigurationParameter(int key, const QVariant &value);
128     QVariant configurationParameter(int key) const;
129     QVector<int> configurationKeys() const;
130 
131     virtual bool writeFrame(const QCanBusFrame &frame) = 0;
132     QCanBusFrame readFrame();
133     QVector<QCanBusFrame> readAllFrames();
134     qint64 framesAvailable() const;
135     qint64 framesToWrite() const;
136 
137     void resetController();
138     bool hasBusStatus() const;
139     QCanBusDevice::CanBusStatus busStatus() const;
140 
141     enum Direction {
142         Input = 1,
143         Output = 2,
144         AllDirections = Input | Output
145     };
146     Q_DECLARE_FLAGS(Directions, Direction)
147     void clear(Directions direction = Direction::AllDirections);
148 
149     virtual bool waitForFramesWritten(int msecs);
150     virtual bool waitForFramesReceived(int msecs);
151 
152     // TODO rename these once QIODevice dependency has been removed
153     bool connectDevice();
154     void disconnectDevice();
155 
156     CanBusDeviceState state() const;
157 
158     CanBusError error() const;
159     QString errorString() const;
160 
161     virtual QString interpretErrorFrame(const QCanBusFrame &errorFrame) = 0;
162 
163 Q_SIGNALS:
164     void errorOccurred(QCanBusDevice::CanBusError);
165     void framesReceived();
166     void framesWritten(qint64 framesCount);
167     void stateChanged(QCanBusDevice::CanBusDeviceState state);
168 
169 protected:
170     void setState(QCanBusDevice::CanBusDeviceState newState);
171     void setError(const QString &errorText, QCanBusDevice::CanBusError);
172     void clearError();
173 
174     void enqueueReceivedFrames(const QVector<QCanBusFrame> &newFrames);
175 
176     void enqueueOutgoingFrame(const QCanBusFrame &newFrame);
177     QCanBusFrame dequeueOutgoingFrame();
178     bool hasOutgoingFrames() const;
179 
180     // TODO Remove once official plugin system is gone
181     //      Can be folded into one call to connectDevice() & disconnectDevice()
182     virtual bool open() = 0;
183     virtual void close() = 0;
184 
185     void setResetControllerFunction(std::function<void()> resetter);
186     void setCanBusStatusGetter(std::function<CanBusStatus()> busStatusGetter);
187 
188     static QCanBusDeviceInfo createDeviceInfo(const QString &name,
189                                               bool isVirtual = false,
190                                               bool isFlexibleDataRateCapable = false);
191     static QCanBusDeviceInfo createDeviceInfo(const QString &name, const QString &serialNumber,
192                                               const QString &description, int channel,
193                                               bool isVirtual, bool isFlexibleDataRateCapable);
194 };
195 
196 Q_DECLARE_TYPEINFO(QCanBusDevice::CanBusError, Q_PRIMITIVE_TYPE);
197 Q_DECLARE_TYPEINFO(QCanBusDevice::CanBusDeviceState, Q_PRIMITIVE_TYPE);
198 Q_DECLARE_TYPEINFO(QCanBusDevice::ConfigurationKey, Q_PRIMITIVE_TYPE);
199 Q_DECLARE_TYPEINFO(QCanBusDevice::Filter, Q_PRIMITIVE_TYPE);
200 Q_DECLARE_TYPEINFO(QCanBusDevice::Filter::FormatFilter, Q_PRIMITIVE_TYPE);
201 
202 Q_DECLARE_OPERATORS_FOR_FLAGS(QCanBusDevice::Filter::FormatFilters)
203 Q_DECLARE_OPERATORS_FOR_FLAGS(QCanBusDevice::Directions)
204 
205 QT_END_NAMESPACE
206 
207 Q_DECLARE_METATYPE(QCanBusDevice::Filter::FormatFilter)
208 Q_DECLARE_METATYPE(QList<QCanBusDevice::Filter>)
209 
210 #endif // QCANBUSDEVICE_H
211