98 lines
3.9 KiB
C++
98 lines
3.9 KiB
C++
#include "dbc_decoder.h"
|
|
|
|
#include <iostream>
|
|
#include <limits>
|
|
|
|
struct DecodeCase {
|
|
const char *name;
|
|
ByteOrder byteOrder;
|
|
std::uint32_t startBit;
|
|
std::uint32_t length;
|
|
ValueType valueType;
|
|
std::vector<std::uint8_t> data;
|
|
bool valid;
|
|
std::int64_t rawValue;
|
|
double factor;
|
|
double offset;
|
|
double physicalValue;
|
|
};
|
|
|
|
int main() {
|
|
const DecodeCase cases[] = {
|
|
{"Motorola reproduction", ByteOrder::Motorola, 7U, 16U, ValueType::Unsigned,
|
|
{0x12, 0x34}, true, 0x1234, 1.0, 0.0, 4660.0},
|
|
{"Motorola within byte", ByteOrder::Motorola, 5U, 4U, ValueType::Unsigned,
|
|
{0xAC}, true, 11, 1.0, 0.0, 11.0},
|
|
{"Motorola unaligned crossing", ByteOrder::Motorola, 3U, 12U, ValueType::Unsigned,
|
|
{0xAB, 0xCD}, true, 0xBCD, 1.0, 0.0, 3021.0},
|
|
{"Motorola starts at bit zero", ByteOrder::Motorola, 0U, 2U, ValueType::Unsigned,
|
|
{0x01, 0x80}, true, 3, 1.0, 0.0, 3.0},
|
|
{"Motorola second byte", ByteOrder::Motorola, 15U, 16U, ValueType::Unsigned,
|
|
{0xFF, 0x12, 0x34}, true, 0x1234, 1.0, 0.0, 4660.0},
|
|
{"Motorola signed scaled", ByteOrder::Motorola, 7U, 16U, ValueType::Signed,
|
|
{0xFF, 0xFE}, true, -2, 0.5, 10.0, 9.0},
|
|
{"Motorola 64 bits", ByteOrder::Motorola, 7U, 64U, ValueType::Unsigned,
|
|
{0, 0, 0, 0, 0, 0, 0x12, 0x34}, true, 0x1234, 1.0, 0.0, 4660.0},
|
|
{"Motorola 64 bits high bit", ByteOrder::Motorola, 7U, 64U, ValueType::Unsigned,
|
|
{0x40, 0, 0, 0, 0, 0, 0, 0}, true, 0x4000000000000000LL,
|
|
1.0, 0.0, 4611686018427387904.0},
|
|
{"Motorola short payload", ByteOrder::Motorola, 7U, 16U, ValueType::Unsigned,
|
|
{0x12}, false, 0, 1.0, 0.0, 0.0},
|
|
{"Motorola empty payload", ByteOrder::Motorola, 7U, 8U, ValueType::Unsigned,
|
|
{}, false, 0, 1.0, 0.0, 0.0},
|
|
{"Motorola large start", ByteOrder::Motorola,
|
|
std::numeric_limits<std::uint32_t>::max(), 8U, ValueType::Unsigned,
|
|
{0xFF}, false, 0, 1.0, 0.0, 0.0},
|
|
{"Motorola zero length", ByteOrder::Motorola, 7U, 0U, ValueType::Unsigned,
|
|
{0xFF}, false, 0, 1.0, 0.0, 0.0},
|
|
{"Motorola excessive length", ByteOrder::Motorola, 7U, 65U, ValueType::Unsigned,
|
|
std::vector<std::uint8_t> (9U, 0xFF), false, 0, 1.0, 0.0, 0.0},
|
|
{"Intel regression", ByteOrder::Intel, 0U, 16U, ValueType::Unsigned,
|
|
{0x12, 0x34}, true, 0x3412, 1.0, 0.0, 13330.0},
|
|
{"Intel signed regression", ByteOrder::Intel, 0U, 16U, ValueType::Signed,
|
|
{0xFE, 0xFF}, true, -2, 0.5, 10.0, 9.0},
|
|
{"Intel short payload", ByteOrder::Intel, 0U, 16U, ValueType::Unsigned,
|
|
{0x12}, false, 0, 1.0, 0.0, 0.0}
|
|
};
|
|
|
|
int failures = 0;
|
|
for (const DecodeCase &test : cases) {
|
|
DecodeSignal signal;
|
|
signal.name = test.name;
|
|
signal.byteOrder = test.byteOrder;
|
|
signal.startBit = test.startBit;
|
|
signal.length = test.length;
|
|
signal.valueType = test.valueType;
|
|
signal.factor = test.factor;
|
|
signal.offset = test.offset;
|
|
|
|
DecodeFrame definition;
|
|
definition.canId = 0x123U;
|
|
definition.dlc = static_cast<std::uint8_t> (test.data.size());
|
|
definition.signals.push_back (signal);
|
|
DecodeDatabase database;
|
|
database.frames.push_back (definition);
|
|
database.frameIndexByKey.emplace (FrameKey (definition.canId, false), 0U);
|
|
|
|
RawCanFrame frame;
|
|
frame.canId = definition.canId;
|
|
frame.data = test.data;
|
|
const DecodedFrameValue result = DbcDecoder().Decode (database, frame);
|
|
const bool passed = result.valid &&
|
|
(result.definition == &database.frames[0]) &&
|
|
(result.signals.size() == 1U) &&
|
|
(result.signals[0].definition == &database.frames[0].signals[0]) &&
|
|
(result.signals[0].valid == test.valid) &&
|
|
(!test.valid || ((result.signals[0].rawValue == test.rawValue) &&
|
|
(result.signals[0].physicalValue == test.physicalValue)));
|
|
if (!passed) {
|
|
std::cerr << "FAIL: " << test.name << '\n';
|
|
++failures;
|
|
}
|
|
}
|
|
if (failures != 0)
|
|
return 1;
|
|
std::cout << "All " << sizeof (cases) / sizeof (cases[0]) << " decoder cases passed.\n";
|
|
return 0;
|
|
}
|