13#include "signal_layout.h"
19 bool isExtended)
const {
29 if (definition ==
nullptr)
34 result.
status = frame.
data.size() < definition->dlc
35 ? FrameDecodeStatus::InsufficientPayload
36 : FrameDecodeStatus::Valid;
38 const SelectorState selector = ReadSelector(*definition, frame);
39 result.signals.reserve(definition->signals.size());
41 DecodedSignalValue decoded = DecodeOneSignal(signal, definition->dlc, frame, selector);
42 if (!decoded.
valid && decoded.status != SignalDecodeStatus::Inactive &&
43 result.
status == FrameDecodeStatus::Valid)
44 result.
status = FrameDecodeStatus::SignalErrors;
45 decoded.
definition = std::shared_ptr<const DecodeSignal>(definition, &signal);
47 result.signals.push_back(std::move(decoded));
53bool DbcDecoder::IsValidDefinition(
const DecodeSignal &signal, std::uint8_t dlc) {
57 (signal.multiplexing.role != MultiplexRole::Unconditional &&
58 signal.multiplexing.role != MultiplexRole::Selector &&
59 signal.multiplexing.role != MultiplexRole::Branch))
63 signal.
byteOrder == ByteOrder::Intel, dlc);
66DbcDecoder::SelectorState DbcDecoder::ReadSelector(
const DecodeFrame &definition,
68 SelectorState selector;
69 std::size_t count = 0U;
71 if (signal.multiplexing.role == MultiplexRole::Selector) {
72 selector.definition = &signal;
80 selector.valid = signal.
valueType == ValueType::Unsigned &&
81 IsValidDefinition(signal, definition.
dlc);
82 selector.available = selector.valid && ExtractUnsigned(frame.
data, signal, selector.value);
89 const SelectorState &selector) {
91 std::uint64_t unsignedValue = 0U;
93 if (!IsValidDefinition(signal, dlc) ||
94 (signal.multiplexing.role != MultiplexRole::Unconditional && !selector.valid)) {
97 if (signal.multiplexing.role == MultiplexRole::Branch) {
98 if (selector.definition->length < 64U && signal.multiplexing.value >= (std::uint64_t(1U) << selector.definition->length)) {
101 if (!selector.available) {
102 decoded.status = SignalDecodeStatus::SelectorUnavailable;
105 if (signal.multiplexing.value != selector.value) {
106 decoded.status = SignalDecodeStatus::Inactive;
110 if (!ExtractUnsigned(frame.
data, signal, unsignedValue)) {
111 decoded.status = SignalDecodeStatus::InsufficientPayload;
115 if (signal.
valueType == ValueType::Signed)
121 if (
const std::int64_t *signedValue = std::get_if<std::int64_t>(&decoded.
rawValue))
122 numericValue =
static_cast<double>(*signedValue);
124 numericValue =
static_cast<double>(std::get<std::uint64_t>(decoded.
rawValue));
127 decoded.status = SignalDecodeStatus::PhysicalConversionFailed;
130 decoded.
valid =
true;
131 decoded.status = SignalDecodeStatus::Valid;
136bool DbcDecoder::ExtractUnsigned(
const std::vector<std::uint8_t> &data,
138 std::uint64_t &value) {
142 if (signal.
byteOrder == ByteOrder::Intel)
145 return ExtractMotorola(data, signal.
startBit, signal.
length, value);
148bool DbcDecoder::ExtractIntel(
const std::vector<std::uint8_t> &data,
149 std::uint32_t startBit,
150 std::uint32_t length,
151 std::uint64_t &value) {
154 for (std::uint32_t bitIndex = 0U; bitIndex < length; ++bitIndex) {
155 const std::uint64_t absoluteBit = std::uint64_t(startBit) + bitIndex;
156 const std::uint64_t byteIndex = absoluteBit / 8U;
157 const std::uint32_t bitInByte = absoluteBit % 8U;
159 if (byteIndex >= data.size())
162 const std::uint64_t bitValue =
163 (
static_cast<std::uint64_t
>((data[byteIndex] >> bitInByte) & 0x01U) << bitIndex);
171bool DbcDecoder::ExtractMotorola(
const std::vector<std::uint8_t> &data,
172 std::uint32_t startBit,
173 std::uint32_t length,
174 std::uint64_t &value) {
185 std::size_t byteIndex = startBit / 8U;
186 std::uint32_t bitInByte = startBit % 8U;
188 for (std::uint32_t bitIndex = 0U; bitIndex < length; ++bitIndex) {
189 if (byteIndex >= data.size())
193 value |=
static_cast<std::uint64_t
>((data[byteIndex] >> bitInByte) & 0x01U);
195 if (bitInByte == 0U) {
205std::int64_t DbcDecoder::SignExtend(std::uint64_t value, std::uint32_t bitLength) {
206 if ((bitLength == 0U) || (bitLength > 64U))
209 const std::uint64_t signMask = std::uint64_t(1U) << (bitLength - 1U);
210 const std::uint64_t valueMask = (bitLength == 64U)
212 : (std::uint64_t(1U) << bitLength) - 1U;
215 if ((value & signMask) == 0U)
216 return static_cast<std::int64_t
>(value);
219 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