DBC Framework
DBC parsing and CAN signal decoding framework
Loading...
Searching...
No Matches
dbc_pipeline_test.cpp
2#include "dbc_decoder.h"
3#include "dbc_parser.h"
4#include "dbc_tree_builder.h"
5#include <QTemporaryFile>
6#include <QtTest>
7#include <stdexcept>
8#include <utility>
9
10namespace {
11 const std::string fixture = R"DBC(BO_ 291 Standard: 2 SenderA
12 SG_ Mode M : 0|8@1+ (1,0) [0|255] "" ReceiverA
13 SG_ State m3 : 8|8@1+ (2,1) [1|511] "km/h" ReceiverA,ReceiverB
14BO_ 2147483939 Extended: 1 SenderB
15 SG_ State : 7|8@0- (0.5,-3) [-67|60.5] "deg C" ReceiverB
16BO_ 2565866562 J1939: 0 SenderC
17CM_ BO_ 291 "Standard frame comment";
18CM_ SG_ 291 Mode "Selector comment";
19CM_ SG_ 291 State "Standard signal comment";
20CM_ BO_ 2147483939 "Extended frame comment";
21CM_ SG_ 2147483939 State "Extended signal comment";
22VAL_ 291 Mode 3 "Selected";
23VAL_ 291 State 4 "Standard four";
24VAL_ 2147483939 State -2 "Extended minus two";
25)DBC";
26
27 DbcParseResult ParseFixture(const std::string &text) {
28 QTemporaryFile file;
29 if (!file.open()) throw std::runtime_error("Cannot create DBC fixture");
30 if (file.write(text.data(), static_cast<qint64>(text.size())) != static_cast<qint64>(text.size()) || !file.flush())
31 throw std::runtime_error("Cannot write DBC fixture");
32 return DbcParser(DbcParserOptions{true}).ParseFileWithDiagnostics(file.fileName().toStdString());
33 }
34
35 // Independent expectations ensure a parser regression cannot be hidden by
36 // comparing builders only with the same incorrect parsed input.
37 DbcDatabase ExpectedMetadata() {
38 FrameInfo standard;
39 standard.name = "Standard";
40 standard.canId = 291U;
41 standard.dlc = 2U;
42 standard.transmitter = "SenderA";
43 standard.comment = "Standard frame comment";
44 SignalInfo mode;
45 mode.name = "Mode";
46 mode.multiplexing.role = MultiplexRole::Selector;
47 mode.length = 8U;
48 mode.maximum = 255;
49 mode.receivers = {"ReceiverA"};
50 mode.comment = "Selector comment";
51 mode.valueDescriptions = {{std::uint64_t(3), "Selected"}};
52 SignalInfo state;
53 state.name = "State";
54 state.multiplexing.role = MultiplexRole::Branch;
55 state.multiplexing.value = 3U;
56 state.startBit = 8U;
57 state.length = 8U;
58 state.factor = 2;
59 state.offset = 1;
60 state.minimum = 1;
61 state.maximum = 511;
62 state.unit = "km/h";
63 state.receivers = {"ReceiverA", "ReceiverB"};
64 state.comment = "Standard signal comment";
65 state.valueDescriptions = {{std::uint64_t(4), "Standard four"}};
66 standard.signals = {mode, state};
67
68 FrameInfo extended;
69 extended.name = "Extended";
70 extended.canId = 291U;
71 extended.isExtended = true;
72 extended.hasPgn = true;
73 extended.dlc = 1U;
74 extended.transmitter = "SenderB";
75 extended.comment = "Extended frame comment";
76 state.multiplexing = Multiplexing();
77 state.startBit = 7U;
78 state.isLittleEndian = false;
79 state.isSigned = true;
80 state.factor = 0.5;
81 state.offset = -3;
82 state.minimum = -67;
83 state.maximum = 60.5;
84 state.unit = "deg C";
85 state.receivers = {"ReceiverB"};
86 state.comment = "Extended signal comment";
87 state.valueDescriptions = {{std::int64_t(-2), "Extended minus two"}};
88 extended.signals = {state};
89
90 FrameInfo j1939;
91 j1939.name = "J1939";
92 j1939.canId = 0x18F00442U;
93 j1939.isExtended = true;
94 j1939.hasPgn = true;
95 j1939.pgn = 0xF004U;
96 j1939.transmitter = "SenderC";
97 return DbcDatabase{{standard, extended, j1939}};
98 }
99
100 template<class Signal>
101 void CheckSignalMetadata(const Signal &actual, const SignalInfo &expected) {
102 QCOMPARE(actual.name, expected.name);
103 QCOMPARE(actual.startBit, expected.startBit);
104 QCOMPARE(actual.length, expected.length);
105 QCOMPARE(actual.factor, expected.factor);
106 QCOMPARE(actual.offset, expected.offset);
107 QCOMPARE(actual.minimum, expected.minimum);
108 QCOMPARE(actual.maximum, expected.maximum);
109 QCOMPARE(actual.unit, expected.unit);
110 QVERIFY(actual.receivers == expected.receivers);
111 QCOMPARE(actual.comment, expected.comment);
112 QVERIFY(actual.valueDescriptions == expected.valueDescriptions);
113 QCOMPARE(actual.multiplexing.role, expected.multiplexing.role);
114 QCOMPARE(actual.multiplexing.value, expected.multiplexing.value);
115 }
116
117 void CheckSignal(const SignalInfo &actual, const SignalInfo &expected) {
118 CheckSignalMetadata(actual, expected);
119 QCOMPARE(actual.isLittleEndian, expected.isLittleEndian);
120 QCOMPARE(actual.isSigned, expected.isSigned);
121 }
122
123 void CheckSignal(const DecodeSignal &actual, const SignalInfo &expected) {
124 CheckSignalMetadata(actual, expected);
125 QCOMPARE(actual.byteOrder, expected.isLittleEndian ? ByteOrder::Intel : ByteOrder::Motorola);
126 QCOMPARE(actual.valueType, expected.isSigned ? ValueType::Signed : ValueType::Unsigned);
127 }
128
129 template<class Frame>
130 void CheckFrame(const Frame &actual, const FrameInfo &expected) {
131 QCOMPARE(actual.name, expected.name);
132 QCOMPARE(actual.canId, expected.canId);
133 QCOMPARE(actual.isExtended, expected.isExtended);
134 QCOMPARE(actual.dlc, expected.dlc);
135 QCOMPARE(actual.pgn, expected.pgn);
136 QCOMPARE(actual.hasPgn, expected.hasPgn);
137 QCOMPARE(actual.transmitter, expected.transmitter);
138 QCOMPARE(actual.comment, expected.comment);
139 QCOMPARE(actual.signals.size(), expected.signals.size());
140 for (std::size_t i = 0; i < expected.signals.size(); ++i)
141 CheckSignal(actual.signals[i], expected.signals[i]);
142 }
143
144 void CheckTree(const TreeNode &root, const DbcDatabase &expected) {
145 QCOMPARE(root.GetType(), NodeType::Root);
146 QVERIFY(root.GetParent() == nullptr);
147 QVERIFY(root.GetFrame() == nullptr);
148 QVERIFY(root.GetSignal() == nullptr);
149 QCOMPARE(root.GetChildCount(), expected.frames.size());
150 for (std::size_t i = 0; i < expected.frames.size(); ++i) {
151 const TreeNode *frame = root.GetChild(i);
152 QVERIFY(frame != nullptr);
153 QCOMPARE(frame->GetType(), NodeType::Frame);
154 QCOMPARE(frame->GetParent(), &root);
155 QCOMPARE(frame->GetRow(), i);
156 QCOMPARE(frame->GetName(), expected.frames[i].name);
157 QVERIFY(frame->GetFrame() != nullptr);
158 QVERIFY(frame->GetSignal() == nullptr);
159 CheckFrame(*frame->GetFrame(), expected.frames[i]);
160 QCOMPARE(frame->GetChildCount(), expected.frames[i].signals.size());
161 for (std::size_t j = 0; j < frame->GetChildCount(); ++j) {
162 const TreeNode *signal = frame->GetChild(j);
163 QVERIFY(signal != nullptr);
164 QCOMPARE(signal->GetType(), NodeType::Signal);
165 QCOMPARE(signal->GetParent(), frame);
166 QCOMPARE(signal->GetRow(), j);
167 QCOMPARE(signal->GetName(), expected.frames[i].signals[j].name);
168 QVERIFY(signal->GetSignal() != nullptr);
169 QVERIFY(signal->GetFrame() == nullptr);
170 QCOMPARE(signal->GetChildCount(), std::size_t(0));
171 CheckSignal(*signal->GetSignal(), expected.frames[i].signals[j]);
172 }
173 }
174 QVERIFY(root.GetChild(expected.frames.size()) == nullptr);
175 }
176
177 void CheckUnknown(const DecodeDatabase &runtime, bool extended) {
178 const FrameKey key(291U, extended);
179 QVERIFY(runtime.FindFrame(key) == nullptr);
180 QVERIFY(runtime.FindSignal(SignalKey(key, "State")) == nullptr);
181 QVERIFY(DbcDecoder().FindFrame(runtime, key.canId, key.isExtended) == nullptr);
182 RawCanFrame raw;
183 raw.canId = key.canId;
184 raw.isExtended = extended;
185 raw.data = {3U, 4U};
186 const DecodedFrameValue decoded = DbcDecoder().Decode(runtime, raw);
187 QVERIFY(!decoded.valid);
188 QCOMPARE(decoded.status, FrameDecodeStatus::UnknownFrame);
189 QVERIFY(decoded.definition == nullptr);
190 QVERIFY(decoded.signals.empty());
191 QVERIFY(decoded.key == key);
192 }
193}// namespace
194
195class PipelineTest : public QObject {
196 Q_OBJECT
197private Q_SLOTS:
198 void metadataLookupDecodeAndTree();
199 void emptyDatabase_data();
200 void emptyDatabase();
201 void databaseReplacement();
202 void unsupportedSignalTypes_data();
203 void unsupportedSignalTypes();
204};
205
206void PipelineTest::metadataLookupDecodeAndTree() {
207 const DbcParseResult parsed = ParseFixture(fixture);
208 QVERIFY(!parsed.HasErrors());
209 QVERIFY(parsed.diagnostics.empty());
210 const DbcDatabase expected = ExpectedMetadata();
211 QCOMPARE(parsed.database.frames.size(), expected.frames.size());
212 const DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed.database);
213 QCOMPARE(runtime.GetFrames().size(), expected.frames.size());
214 const std::unique_ptr<TreeNode> tree = DbcTreeBuilder().Build(parsed.database);
215 QVERIFY(tree != nullptr);
216 CheckTree(*tree, expected);
217 for (std::size_t i = 0; i < expected.frames.size(); ++i) {
218 CheckFrame(parsed.database.frames[i], expected.frames[i]);
219 CheckFrame(runtime.GetFrames()[i], expected.frames[i]);
220 const FrameKey key(expected.frames[i].canId, expected.frames[i].isExtended);
221 const std::shared_ptr<const DecodeFrame> found = runtime.FindFrame(key);
222 QVERIFY(found != nullptr);
223 QCOMPARE(found.get(), &runtime.GetFrames()[i]);
224 QCOMPARE(DbcDecoder().FindFrame(runtime, key.canId, key.isExtended).get(), found.get());
225 for (std::size_t j = 0; j < found->signals.size(); ++j) {
226 const std::shared_ptr<const DecodeSignal> signal = runtime.FindSignal(SignalKey(key, found->signals[j].name));
227 QVERIFY(signal != nullptr);
228 QCOMPARE(signal.get(), &found->signals[j]);
229 }
230 }
231 QVERIFY(runtime.FindSignal(SignalKey(FrameKey(291U, true), "Mode")) == nullptr);
232 QVERIFY(runtime.FindFrame(FrameKey(292U, false)) == nullptr);
233
234 RawCanFrame raw;
235 raw.canId = 291U;
236 raw.data = {3U, 4U};
237 const DecodedFrameValue standard = DbcDecoder().Decode(runtime, raw);
238 QVERIFY(standard.valid);
239 QCOMPARE(standard.status, FrameDecodeStatus::Valid);
240 QVERIFY(standard.key == FrameKey(291U, false));
241 QCOMPARE(standard.definition.get(), runtime.FindFrame(standard.key).get());
242 QCOMPARE(standard.signals.size(), std::size_t(2));
243 for (std::size_t i = 0; i < standard.signals.size(); ++i) {
244 const DecodedSignalValue &signal = standard.signals[i];
245 QVERIFY(signal.valid);
246 QCOMPARE(signal.status, SignalDecodeStatus::Valid);
247 QVERIFY(signal.key == SignalKey(standard.key, i == 0 ? "Mode" : "State"));
248 QCOMPARE(signal.definition.get(), runtime.FindSignal(signal.key).get());
249 QCOMPARE(std::get<std::uint64_t>(signal.rawValue), i == 0 ? 3U : 4U);
250 QCOMPARE(signal.physicalValue, i == 0 ? 3.0 : 9.0);
251 QVERIFY(signal.GetValueDescription() != nullptr);
252 QCOMPARE(*signal.GetValueDescription(), std::string(i == 0 ? "Selected" : "Standard four"));
253 }
254 raw.isExtended = true;
255 raw.data = {0xFEU};
256 const DecodedFrameValue extended = DbcDecoder().Decode(runtime, raw);
257 QVERIFY(extended.valid);
258 QCOMPARE(extended.status, FrameDecodeStatus::Valid);
259 QVERIFY(extended.key == FrameKey(291U, true));
260 QCOMPARE(extended.definition.get(), runtime.FindFrame(extended.key).get());
261 QCOMPARE(extended.signals.size(), std::size_t(1));
262 const DecodedSignalValue &signal = extended.signals[0];
263 QVERIFY(signal.valid);
264 QCOMPARE(signal.status, SignalDecodeStatus::Valid);
265 QVERIFY(signal.key == SignalKey(extended.key, "State"));
266 QCOMPARE(signal.definition.get(), runtime.FindSignal(signal.key).get());
267 QCOMPARE(std::get<std::int64_t>(signal.rawValue), std::int64_t(-2));
268 QCOMPARE(signal.physicalValue, -4.0);
269 QVERIFY(signal.GetValueDescription() != nullptr);
270 QCOMPARE(*signal.GetValueDescription(), std::string("Extended minus two"));
271
272 raw.canId = 0x18F00442U;
273 raw.data.clear();
274 const DecodedFrameValue j1939 = DbcDecoder().Decode(runtime, raw);
275 QVERIFY(j1939.valid);
276 QCOMPARE(j1939.status, FrameDecodeStatus::Valid);
277 QVERIFY(j1939.key == FrameKey(0x18F00442U, true));
278 QCOMPARE(j1939.definition.get(), runtime.FindFrame(j1939.key).get());
279 QVERIFY(j1939.signals.empty());
280}
281
282void PipelineTest::unsupportedSignalTypes_data() {
283 QTest::addColumn<unsigned>("bits");
284 QTest::addColumn<unsigned>("type");
285 QTest::addColumn<std::vector<std::uint8_t>>("payload");
286 QTest::addColumn<std::uint64_t>("integerValue");
287 QTest::newRow("float32-one") << 32U << 1U << std::vector<std::uint8_t>{0U, 0U, 128U, 63U}
288 << std::uint64_t(0x3F800000U);
289 QTest::newRow("float64-one") << 64U << 2U << std::vector<std::uint8_t>{0U, 0U, 0U, 0U, 0U, 0U, 240U, 63U}
290 << std::uint64_t(0x3FF0000000000000ULL);
291}
292
293void PipelineTest::unsupportedSignalTypes() {
294 QFETCH(unsigned, bits);
295 QFETCH(unsigned, type);
296 QFETCH(std::vector<std::uint8_t>, payload);
297 QFETCH(std::uint64_t, integerValue);
298 const std::string definitions = "BO_ 1 Frame: " + std::to_string(bits / 8U) + " ECU\n"
299 "SG_ Value : 0|" + std::to_string(bits) + "@1+ (1,0) [0|100] \"\" ECU\n";
300 RawCanFrame raw;
301 raw.canId = 1U;
302 raw.data = payload;
303 const DbcDecodeBuilder builder;
304 const DbcDecoder decoder;
305
306 // Without a type override, the same bits are a supported integer signal.
307 const DbcParseResult integers = ParseFixture(definitions);
308 QVERIFY(!integers.HasErrors());
309 const DecodedFrameValue integerFrame = decoder.Decode(builder.Build(integers.database), raw);
310 QCOMPARE(integerFrame.status, FrameDecodeStatus::Valid);
311 QCOMPARE(integerFrame.signals.size(), std::size_t(1));
312 QVERIFY(integerFrame.signals[0].valid);
313 QCOMPARE(std::get<std::uint64_t>(integerFrame.signals[0].rawValue), integerValue);
314
315 const DbcParseResult floatingPoint = ParseFixture(definitions +
316 "SIG_VALTYPE_ 1 Value : " + std::to_string(type) + ";\n");
317 QVERIFY(floatingPoint.HasErrors());
318 QCOMPARE(floatingPoint.diagnostics.size(), std::size_t(1));
319 QCOMPARE(floatingPoint.diagnostics[0].code, DbcDiagnosticCode::UnsupportedSignalType);
320 QCOMPARE(floatingPoint.diagnostics[0].lineNumber, std::size_t(3));
321 QVERIFY(floatingPoint.database.frames.empty());
322 // Even if a caller overlooks the error, no integer definition is published.
323 const DecodedFrameValue rejected = decoder.Decode(builder.Build(floatingPoint.database), raw);
324 QCOMPARE(rejected.status, FrameDecodeStatus::UnknownFrame);
325 QVERIFY(!rejected.valid);
326 QVERIFY(!rejected.definition);
327 QVERIFY(rejected.signals.empty());
328}
329
330void PipelineTest::emptyDatabase_data() {
331 QTest::addColumn<QString>("text");
332 QTest::newRow("empty-file") << QString();
333 QTest::newRow("headers-only") << QString::fromUtf8("VERSION \"empty\"\nNS_ :\nBS_:\nBU_: Sender\n");
334}
335
336void PipelineTest::emptyDatabase() {
337 QFETCH(QString, text);
338 const DbcParseResult parsed = ParseFixture(text.toStdString());
339 QVERIFY(!parsed.HasErrors());
340 QVERIFY(parsed.diagnostics.empty());
341 QVERIFY(parsed.database.frames.empty());
342 const DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed.database);
343 QVERIFY(runtime.GetFrames().empty());
344 CheckUnknown(runtime, false);
345 CheckUnknown(runtime, true);
346 const std::unique_ptr<TreeNode> tree = DbcTreeBuilder().Build(parsed.database);
347 QVERIFY(tree != nullptr);
348 CheckTree(*tree, DbcDatabase());
349}
350
351void PipelineTest::databaseReplacement() {
352 DbcParseResult parsed = ParseFixture(fixture);
353 QVERIFY(!parsed.HasErrors());
354 DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed.database);
355 std::unique_ptr<TreeNode> tree = DbcTreeBuilder().Build(parsed.database);
356 RawCanFrame raw;
357 raw.canId = 291U;
358 raw.data = {3U, 4U};
359 const DecodedFrameValue saved = DbcDecoder().Decode(runtime, raw);
360 QVERIFY(saved.valid);
361 QCOMPARE(saved.signals.size(), std::size_t(2));
362 QVERIFY(tree != nullptr);
363 std::unique_ptr<TreeNode> savedTree = std::move(tree);
364
365 parsed = ParseFixture(R"DBC(BO_ 291 Replacement: 1 NewSender
366 SG_ NewState : 0|8@1+ (3,-1) [-1|764] "V" NewReceiver
367CM_ BO_ 291 "Replacement frame";
368CM_ SG_ 291 NewState "Replacement signal";
369VAL_ 291 NewState 4 "New four";
370)DBC");
371 QVERIFY(!parsed.HasErrors());
372 QVERIFY(parsed.diagnostics.empty());
373 FrameInfo replacement;
374 replacement.name = "Replacement";
375 replacement.canId = 291U;
376 replacement.dlc = 1U;
377 replacement.transmitter = "NewSender";
378 replacement.comment = "Replacement frame";
379 SignalInfo state;
380 state.name = "NewState";
381 state.length = 8U;
382 state.factor = 3;
383 state.offset = -1;
384 state.minimum = -1;
385 state.maximum = 764;
386 state.unit = "V";
387 state.receivers = {"NewReceiver"};
388 state.comment = "Replacement signal";
389 state.valueDescriptions = {{std::uint64_t(4), "New four"}};
390 replacement.signals = {state};
391 const DbcDatabase expected{{replacement}};
392 QCOMPARE(parsed.database.frames.size(), std::size_t(1));
393 CheckFrame(parsed.database.frames[0], replacement);
394 runtime = DbcDecodeBuilder().Build(parsed.database);
395 tree = DbcTreeBuilder().Build(parsed.database);
396 QVERIFY(tree != nullptr);
397 QCOMPARE(runtime.GetFrames().size(), std::size_t(1));
398 CheckFrame(runtime.GetFrames()[0], replacement);
399 CheckTree(*tree, expected);
400 CheckUnknown(runtime, true);
401 QVERIFY(runtime.FindFrame(FrameKey(0x18F00442U, true)) == nullptr);
402 QVERIFY(runtime.FindSignal(SignalKey(FrameKey(291U, false), "State")) == nullptr);
403 QVERIFY(runtime.FindSignal(SignalKey(FrameKey(291U, false), "Mode")) == nullptr);
404 raw.data = {4U};
405 const DecodedFrameValue current = DbcDecoder().Decode(runtime, raw);
406 QVERIFY(current.valid);
407 QCOMPARE(current.status, FrameDecodeStatus::Valid);
408 QCOMPARE(current.signals.size(), std::size_t(1));
409 QVERIFY(current.signals[0].valid);
410 QVERIFY(current.signals[0].key == SignalKey(FrameKey(291U, false), "NewState"));
411 QCOMPARE(current.signals[0].definition.get(), runtime.FindSignal(current.signals[0].key).get());
412 QCOMPARE(std::get<std::uint64_t>(current.signals[0].rawValue), std::uint64_t(4));
413 QCOMPARE(current.signals[0].physicalValue, 11.0);
414 QVERIFY(current.signals[0].GetValueDescription() != nullptr);
415 QCOMPARE(*current.signals[0].GetValueDescription(), std::string("New four"));
416
417 parsed = ParseFixture("");
418 QVERIFY(!parsed.HasErrors());
419 QVERIFY(parsed.diagnostics.empty());
420 runtime = DbcDecodeBuilder().Build(parsed.database);
421 tree = DbcTreeBuilder().Build(parsed.database);
422 QVERIFY(tree != nullptr);
423 QVERIFY(runtime.GetFrames().empty());
424 CheckUnknown(runtime, false);
425 CheckUnknown(runtime, true);
426 CheckTree(*tree, DbcDatabase());
427 QVERIFY(runtime.FindSignal(current.signals[0].key) == nullptr);
428 CheckFrame(*current.definition, replacement);
429 CheckFrame(*saved.definition, ExpectedMetadata().frames[0]);
430 CheckTree(*savedTree, ExpectedMetadata());
431 QCOMPARE(saved.signals[1].physicalValue, 9.0);
432 QVERIFY(saved.signals[1].GetValueDescription() != nullptr);
433 QCOMPARE(*saved.signals[1].GetValueDescription(), std::string("Standard four"));
434}
435
436int RunPipelineTests(int argc, char **argv) {
437 PipelineTest test;
438 return QTest::qExec(&test, argc, argv);
439}
440
441#include "dbc_pipeline_test.moc"
Converts parsed DBC data into runtime decode database.
DecodeDatabase Build(const DbcDatabase &source) const
Build runtime decode database.
Runtime CAN decoder using prebuilt decode database.
Definition dbc_decoder.h:87
DecodedFrameValue Decode(const DecodeDatabase &database, const RawCanFrame &frame) const
Decode one raw CAN frame.
Minimal DBC parser.
Definition dbc_parser.h:45
Builds a simple tree from parsed DBC database.
std::unique_ptr< TreeNode > Build(const DbcDatabase &database) const
Build tree representation of parsed DBC data.
Immutable runtime snapshot. Copies share storage; reload replaces a snapshot. Owning lookup handles a...
std::shared_ptr< const DecodeSignal > FindSignal(const SignalKey &key) const
Return an owning signal handle, or an empty handle for a missing key.
std::shared_ptr< const DecodeFrame > FindFrame(const FrameKey &key) const
const std::vector< DecodeFrame > & GetFrames() const
Tree node for later use in model/view or other hierarchy consumers.
Definition tree_node.h:37
const SignalInfo * GetSignal() const
Get signal payload if node is signal.
Definition tree_node.cpp:71
const TreeNode * GetChild(std::size_t index) const
Get child by index.
Definition tree_node.cpp:45
const TreeNode * GetParent() const
Definition tree_node.cpp:75
const std::string & GetName() const
Get display name.
Definition tree_node.cpp:63
std::size_t GetChildCount() const
Get child count.
Definition tree_node.cpp:41
std::size_t GetRow() const
Definition tree_node.cpp:79
NodeType GetType() const
Get node type.
Definition tree_node.cpp:59
const FrameInfo * GetFrame() const
Get frame payload if node is frame.
Definition tree_node.cpp:67
Runtime decode database builder.
CAN frame decoding API and result types.
DBC file parser and interpretation options.
Metadata tree builder.
ByteOrder
Signal byte order used for runtime decoding.
ValueType
Signal numeric type.
Parsed DBC content stored in a simple internal form.
std::vector< FrameInfo > frames
Parsed database and diagnostics; the database is empty on error.
std::vector< DbcDiagnostic > diagnostics
bool HasErrors() const
Return whether any diagnostic has error severity.
DbcDatabase database
Runtime-ready signal definition.
ValueType valueType
ByteOrder byteOrder
Fully decoded frame.
Definition dbc_decoder.h:74
std::shared_ptr< const DecodeFrame > definition
Definition dbc_decoder.h:75
FrameDecodeStatus status
Definition dbc_decoder.h:79
One decoded signal value.
Definition dbc_decoder.h:55
RawSignalValue rawValue
Definition dbc_decoder.h:58
std::shared_ptr< const DecodeSignal > definition
Definition dbc_decoder.h:56
SignalDecodeStatus status
Definition dbc_decoder.h:61
const std::string * GetValueDescription() const
Definition dbc_decoder.h:64
Describes one CAN frame from a DBC file.
Definition frame_info.h:25
bool isExtended
Definition frame_info.h:28
bool hasPgn
Definition frame_info.h:30
std::string transmitter
Definition frame_info.h:32
std::uint8_t dlc
Definition frame_info.h:31
std::string name
Definition frame_info.h:26
std::string comment
Definition frame_info.h:33
std::uint32_t pgn
Definition frame_info.h:29
std::uint32_t canId
Definition frame_info.h:27
Stable frame identifier: normalized CAN ID and frame type.
Basic markers and optional explicit extended multiplexing condition.
std::uint64_t value
Raw CAN frame used for runtime or trace decoding.
Definition dbc_decoder.h:25
std::vector< std::uint8_t > data
Definition dbc_decoder.h:28
std::uint32_t canId
Definition dbc_decoder.h:26
bool isExtended
Definition dbc_decoder.h:27
Describes one signal inside a DBC frame.
Definition signal_info.h:25
std::uint32_t length
Definition signal_info.h:29
std::string unit
Definition signal_info.h:36
std::vector< std::string > receivers
Definition signal_info.h:37
std::string name
Definition signal_info.h:27
ValueDescriptions valueDescriptions
Definition signal_info.h:38
bool isSigned
Definition signal_info.h:31
Multiplexing multiplexing
Definition signal_info.h:26
double offset
Definition signal_info.h:33
std::string comment
Definition signal_info.h:39
std::uint32_t startBit
Definition signal_info.h:28
double minimum
Definition signal_info.h:34
double maximum
Definition signal_info.h:35
double factor
Definition signal_info.h:32
bool isLittleEndian
Definition signal_info.h:30