18 bool isExtended)
const {
28 if (definition ==
nullptr)
33 result.
status = frame.
data.size() < definition->dlc
34 ? FrameDecodeStatus::InsufficientPayload
35 : FrameDecodeStatus::Valid;
37 const SelectorState selector = ReadSelector(*definition, frame);
38 result.signals.reserve(definition->signals.size());
40 DecodedSignalValue decoded = DecodeOneSignal(signal, definition->dlc, frame, selector);
41 if (!decoded.
valid && decoded.status != SignalDecodeStatus::Inactive &&
42 result.
status == FrameDecodeStatus::Valid)
43 result.
status = FrameDecodeStatus::SignalErrors;
44 decoded.
definition = std::shared_ptr<const DecodeSignal>(definition, &signal);
46 result.signals.push_back(std::move(decoded));
52bool DbcDecoder::IsValidDefinition(
const DecodeSignal &signal, std::uint8_t dlc) {
56 (signal.multiplexing.role != MultiplexRole::Unconditional &&
57 signal.multiplexing.role != MultiplexRole::Selector &&
58 signal.multiplexing.role != MultiplexRole::Branch))
62 const std::uint64_t start = signal.
byteOrder == ByteOrder::Intel
65 return start + signal.
length <= std::uint64_t(dlc) * 8U;
68DbcDecoder::SelectorState DbcDecoder::ReadSelector(
const DecodeFrame &definition,
70 SelectorState selector;
71 std::size_t count = 0U;
73 if (signal.multiplexing.role == MultiplexRole::Selector) {
74 selector.definition = &signal;
82 selector.valid = signal.
valueType == ValueType::Unsigned &&
83 IsValidDefinition(signal, definition.
dlc);
84 selector.available = selector.valid && ExtractUnsigned(frame.
data, signal, selector.value);
91 const SelectorState &selector) {
93 std::uint64_t unsignedValue = 0U;
95 if (!IsValidDefinition(signal, dlc) ||
96 (signal.multiplexing.role != MultiplexRole::Unconditional && !selector.valid)) {
99 if (signal.multiplexing.role == MultiplexRole::Branch) {
100 if (selector.definition->length < 64U && signal.multiplexing.value >= (std::uint64_t(1U) << selector.definition->length)) {
103 if (!selector.available) {
104 decoded.status = SignalDecodeStatus::SelectorUnavailable;
107 if (signal.multiplexing.value != selector.value) {
108 decoded.status = SignalDecodeStatus::Inactive;
112 if (!ExtractUnsigned(frame.
data, signal, unsignedValue)) {
113 decoded.status = SignalDecodeStatus::InsufficientPayload;
117 if (signal.
valueType == ValueType::Signed)
123 if (
const std::int64_t *signedValue = std::get_if<std::int64_t>(&decoded.
rawValue))
124 numericValue =
static_cast<double>(*signedValue);
126 numericValue =
static_cast<double>(std::get<std::uint64_t>(decoded.
rawValue));
129 decoded.status = SignalDecodeStatus::PhysicalConversionFailed;
132 decoded.
valid =
true;
133 decoded.status = SignalDecodeStatus::Valid;
138bool DbcDecoder::ExtractUnsigned(
const std::vector<std::uint8_t> &data,
140 std::uint64_t &value) {
144 if (signal.
byteOrder == ByteOrder::Intel)
147 return ExtractMotorola(data, signal.
startBit, signal.
length, value);
150bool DbcDecoder::ExtractIntel(
const std::vector<std::uint8_t> &data,
151 std::uint32_t startBit,
152 std::uint32_t length,
153 std::uint64_t &value) {
156 for (std::uint32_t bitIndex = 0U; bitIndex < length; ++bitIndex) {
157 const std::uint32_t absoluteBit = startBit + bitIndex;
158 const std::uint32_t byteIndex = absoluteBit / 8U;
159 const std::uint32_t bitInByte = absoluteBit % 8U;
161 if (byteIndex >= data.size())
164 const std::uint64_t bitValue =
165 (
static_cast<std::uint64_t
>((data[byteIndex] >> bitInByte) & 0x01U) << bitIndex);
173bool DbcDecoder::ExtractMotorola(
const std::vector<std::uint8_t> &data,
174 std::uint32_t startBit,
175 std::uint32_t length,
176 std::uint64_t &value) {
187 std::size_t byteIndex = startBit / 8U;
188 std::uint32_t bitInByte = startBit % 8U;
190 for (std::uint32_t bitIndex = 0U; bitIndex < length; ++bitIndex) {
191 if (byteIndex >= data.size())
195 value |=
static_cast<std::uint64_t
>((data[byteIndex] >> bitInByte) & 0x01U);
197 if (bitInByte == 0U) {
207std::int64_t DbcDecoder::SignExtend(std::uint64_t value, std::uint32_t bitLength) {
208 if ((bitLength == 0U) || (bitLength > 64U))
211 const std::uint64_t signMask = std::uint64_t(1U) << (bitLength - 1U);
212 const std::uint64_t valueMask = (bitLength == 64U)
214 : (std::uint64_t(1U) << bitLength) - 1U;
217 if ((value & signMask) == 0U)
218 return static_cast<std::int64_t
>(value);
221 return -1 -
static_cast<std::int64_t
>((~value) & valueMask);
DecodedFrameValue Decode(const DecodeDatabase &database, const RawCanFrame &frame) const
Decode one raw CAN frame.
std::shared_ptr< const DecodeFrame > FindFrame(const DecodeDatabase &database, std::uint32_t canId, bool isExtended) const
Find frame definition by CAN ID.
Immutable runtime snapshot. Copies share storage; reload replaces a snapshot. Owning lookup handles a...
std::shared_ptr< const DecodeFrame > FindFrame(const FrameKey &key) const
Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
Runtime-ready frame definition.
Runtime-ready signal definition.
std::shared_ptr< const DecodeFrame > definition
One decoded signal value.
std::shared_ptr< const DecodeSignal > definition
Stable frame identifier: normalized CAN ID and frame type.
Raw CAN frame used for runtime or trace decoding.
std::vector< std::uint8_t > data