CANdevStudio
Development tool for CAN bus simulation
Loading...
Searching...
No Matches
candevice_p.h
Go to the documentation of this file.
1#ifndef __CANDEVICE_P_H
2#define __CANDEVICE_P_H
3
4#include "candevice.h"
5#include "candeviceqt.h"
6#include <QJsonArray>
7#include <QJsonDocument>
8#include <QJsonObject>
9#include <QJsonValue>
10#include <QtCore/QVector>
11#include <propertyfields.h>
12
13class CanDevicePrivate : public QObject {
14 Q_OBJECT
15 Q_DECLARE_PUBLIC(CanDevice)
16
17public:
19 : _ctx(std::move(ctx))
21 , q_ptr(q)
22 {
23 initProps();
25 }
26
27 void saveSettings(QJsonObject& json)
28 {
29 QJsonArray viewModelsArray;
30
31 for (const auto& p : _props) {
32 json[p.first] = QJsonValue::fromVariant(p.second);
33 }
34 }
35
36 bool restoreConfiguration(const QJsonObject& json)
37 {
38 for (const auto& p : _supportedProps) {
39 QString propName = ComponentInterface::propertyName(p);
40 if (json.contains(propName))
41 _props[propName] = json[propName].toVariant();
42 }
43 return true;
44 }
45
46 using devConfigPair = std::pair<int, QVariant>;
47 std::vector<devConfigPair> getDevConfig()
48 {
49 QString c = _props.at(_configProperty).toString().simplified().replace(" ", "");
50 std::vector<devConfigPair> ret;
51
52 if (c.length() == 0) {
53 // Skip parsing for empty parameter
54 return {};
55 }
56
57 auto&& propList = c.split(";");
58
59 for (auto& item : propList) {
60 devConfigPair pair;
61 bool res = getConfigPair(item, pair);
62
63 if (res) {
64 ret.push_back(pair);
65 }
66 }
67
68 return ret;
69 }
70
71signals:
72 void backendChanged(const QString& backend);
73
74public:
76 QVector<QCanBusFrame> _sendQueue;
78 bool _initialized{ false };
79 bool _simStarted{ false };
80
81 const QString _nameProperty = "name";
82 const QString _backendProperty = "backend";
83 const QString _interfaceProperty = "interface";
84 const QString _configProperty = "configuration";
85
86 // workaround for clang 3.5
88
89 // clang-format off
91 std::make_tuple(_nameProperty, QVariant::String, true, cf(nullptr)),
92
93#if QT_VERSION >= 0x050900
94
95 std::make_tuple(_backendProperty, QVariant::String, true, cf([this] {
96 auto *p = new PropertyFieldCombo();
97 p->addItems(QCanBus::instance()->plugins());
99
100 p->setPropText(_props[_backendProperty].toString());
101
102 return p;
103 })),
104
105 std::make_tuple(_interfaceProperty, QVariant::String, true, cf([&] {
106 auto *p = new PropertyFieldCombo();
107
108 // Connection needs to be destroyed manually. We expect to have only one such conn at a time
109 disconnect(_prevConn);
110 _prevConn = connect(this, &CanDevicePrivate::backendChanged, [p](const QString& backend){
111 QString errorString;
112 const QList<QCanBusDeviceInfo> devices = QCanBus::instance()->availableDevices(
113 backend, &errorString);
114
115 QStringList list;
116 for(auto&& d : devices) {
117 list.append(d.name());
118 }
119
120 if (errorString.isEmpty()) {
121 p->addItems(list);
122 } else {
123 p->setPropText("");
124 cds_error("Failed to get interface for '{}' backend", backend.toStdString());
125 cds_error("{}", errorString.toStdString());
126 }
127 });
128
129 return p;
130 })),
131#else
132 std::make_tuple(_backendProperty, QVariant::String, true, cf(nullptr)),
133 std::make_tuple(_interfaceProperty, QVariant::String, true, cf(nullptr)),
134#endif
135 std::make_tuple(_configProperty, QVariant::String, true, cf(nullptr))
136 };
137 // clang-format on
138
139 std::map<QString, QVariant> _props;
140
141private:
142 void initProps()
143 {
144 for (const auto& p : _supportedProps) {
146 }
147 }
148
149 bool getConfigPair(const QString& in, devConfigPair& out)
150 {
151 auto configStr = in.split("=");
152
153 if ((configStr.length() != 2) || (configStr[1].length() == 0)) {
154 cds_error("Config parameter parse error");
155 return false;
156 }
157
158 auto keyStr = configStr[0];
159 auto valStr = configStr[1];
160
161 QCanBusDevice::ConfigurationKey key;
162 QVariant val;
163 bool res = true;
164
165 if (keyStr == "RawFilterKey") {
166 cds_error("RawFilterKey not supported");
167 res = false;
168 } else if (keyStr == "ErrorFilterKey") {
169 cds_error("ErrorFilterKey not supported");
170 res = false;
171 } else if (keyStr == "LoopbackKey") {
172 key = QCanBusDevice::LoopbackKey;
173 val = valStr.toUpper() == "TRUE";
174 } else if (keyStr == "ReceiveOwnKey") {
175 key = QCanBusDevice::ReceiveOwnKey;
176 val = valStr.toUpper() == "TRUE";
177 } else if (keyStr == "BitRateKey") {
178 key = QCanBusDevice::BitRateKey;
179 val = valStr.toUInt(&res);
180 } else if (keyStr == "CanFdKey") {
181 key = QCanBusDevice::CanFdKey;
182 val = valStr.toUpper() == "TRUE";
183#if QT_VERSION >= 0x050900
184 } else if (keyStr == "DataBitRateKey") {
185 key = QCanBusDevice::DataBitRateKey;
186 val = valStr.toUInt(&res);
187#endif
188 } else if (keyStr == "UserKey") {
189 key = QCanBusDevice::UserKey;
190 val = valStr;
191 } else {
192 cds_error("Failed to convert '{}' to ConfigurationKey", keyStr.toStdString());
193 res = false;
194 }
195
196 if (res) {
197 cds_debug("Key: {}({}), Val: {}", keyStr.toStdString(), key, val.toString().toStdString());
198 out = std::make_pair(key, val);
199 }
200
201 return res;
202 }
203
204 CanDevice* q_ptr;
205 QMetaObject::Connection _prevConn;
206};
207
208#endif /* !__CANDEVICE_P_H */
The class provides abstraction layer for CAN BUS hardware.
Definition candevice.h:15
Definition candevice_p.h:13
CanDeviceCtx _ctx
Definition candevice_p.h:75
void backendChanged(const QString &backend)
std::pair< int, QVariant > devConfigPair
Definition candevice_p.h:46
std::vector< devConfigPair > getDevConfig()
Definition candevice_p.h:47
const QString _backendProperty
Definition candevice_p.h:82
bool _initialized
Definition candevice_p.h:78
const QString _configProperty
Definition candevice_p.h:84
const QString _interfaceProperty
Definition candevice_p.h:83
CanDeviceInterface & _canDevice
Definition candevice_p.h:77
QVector< QCanBusFrame > _sendQueue
Definition candevice_p.h:76
void saveSettings(QJsonObject &json)
Definition candevice_p.h:27
bool restoreConfiguration(const QJsonObject &json)
Definition candevice_p.h:36
CanDevicePrivate(CanDevice *q, CanDeviceCtx &&ctx=CanDeviceCtx(new CanDeviceQt()))
Definition candevice_p.h:18
bool _simStarted
Definition candevice_p.h:79
std::map< QString, QVariant > _props
Definition candevice_p.h:139
ComponentInterface::CustomEditFieldCbk cf
Definition candevice_p.h:87
const QString _nameProperty
Definition candevice_p.h:81
ComponentInterface::ComponentProperties _supportedProps
Definition candevice_p.h:90
Definition propertyfields.h:86
void currentTextChanged(const QString &text)
Context< CanDeviceInterface > CanDeviceCtx
Definition context.h:41
#define cds_debug(fmt,...)
Definition log.h:13
#define cds_error(fmt,...)
Definition log.h:21
Definition candeviceinterface.h:8
virtual void setParent(QObject *parent)=0
Definition candeviceqt.h:9
std::vector< ComponentProperty > ComponentProperties
Definition componentinterface.h:66
std::function< QWidget *(void)> CustomEditFieldCbk
Definition componentinterface.h:64
static constexpr const QString & propertyName(const ComponentProperty &p)
Definition componentinterface.h:69