This commit is contained in:
deeaitch committed 2026-10-23 20:28:55 -04:00
1 parent a702cffd93
commit 8d06165979
18 files changed
+611 -215

No files matched your search

+29 -36
View File
@@ -81,12 +81,14 @@ DecodedFrameValue DbcDecoder::DecodeImpl(const DecodeDatabase &database,
? FrameDecodeStatus::InsufficientPayload
: FrameDecodeStatus::Valid;
const SelectorState selector = ReadSelector(*definition, frame);
const dbc_detail::MultiplexGraph &graph = database.GetMultiplexGraph(result.key);
const std::size_t count = selection != nullptr ? selected.size() : definition->signals.size();
result.signals.reserve(count);
for (std::size_t index = 0U; index < count; ++index) {
const DecodeSignal &signal = selection != nullptr ? *selected[index] : definition->signals[index];
DecodedSignalValue decoded = DecodeOneSignal(signal, definition->dlc, frame, selector);
const std::size_t signalIndex = static_cast<std::size_t>(&signal - definition->signals.data());
DecodedSignalValue decoded = DecodeOneSignal(signal, definition->dlc, frame,
ActivationStatus(signalIndex, *definition, frame, graph));
if (!decoded.valid && decoded.status != SignalDecodeStatus::Inactive &&
result.status == FrameDecodeStatus::Valid)
result.status = FrameDecodeStatus::SignalErrors;
@@ -103,56 +105,47 @@ bool DbcDecoder::IsValidDefinition(const DecodeSignal &signal, std::uint8_t dlc)
(signal.valueType != ValueType::Unsigned && signal.valueType != ValueType::Signed) ||
(signal.multiplexing.role != MultiplexRole::Unconditional &&
signal.multiplexing.role != MultiplexRole::Selector &&
signal.multiplexing.role != MultiplexRole::Branch))
signal.multiplexing.role != MultiplexRole::Branch &&
signal.multiplexing.role != MultiplexRole::BranchSelector))
return false;
return IsValidSignalLayout(signal.startBit, signal.length,
signal.byteOrder == ByteOrder::Intel, dlc);
}
DbcDecoder::SelectorState DbcDecoder::ReadSelector(const DecodeFrame &definition,
const RawCanFrame &frame) {
SelectorState selector;
std::size_t count = 0U;
for (const DecodeSignal &signal: definition.signals) {
if (signal.multiplexing.role == MultiplexRole::Selector) {
selector.definition = &signal;
++count;
}
SignalDecodeStatus DbcDecoder::ActivationStatus(std::size_t index,
const DecodeFrame &definition,
const RawCanFrame &frame,
const dbc_detail::MultiplexGraph &graph) {
// Inspect ancestors from the root so inactive paths never require child bytes.
std::vector<std::size_t> path;
while (graph.parents[index] != definition.signals.size()) {
path.push_back(index);
index = graph.parents[index];
}
if (count != 1U)
return selector;
const DecodeSignal &signal = *selector.definition;
selector.valid = signal.valueType == ValueType::Unsigned &&
IsValidDefinition(signal, definition.dlc);
selector.available = selector.valid && ExtractUnsigned(frame.data, signal, selector.value);
return selector;
for (std::vector<std::size_t>::const_reverse_iterator it = path.rbegin(); it != path.rend(); ++it) {
const DecodeSignal &selector = definition.signals[graph.parents[*it]];
std::uint64_t value = 0U;
if (!ExtractUnsigned(frame.data, selector, value))
return SignalDecodeStatus::SelectorUnavailable;
if (!graph.Matches(*it, value))
return SignalDecodeStatus::Inactive;
}
return SignalDecodeStatus::Valid;
}
DecodedSignalValue DbcDecoder::DecodeOneSignal(const DecodeSignal &signal,
std::uint8_t dlc,
const RawCanFrame &frame,
const SelectorState &selector) {
SignalDecodeStatus activation) {
DecodedSignalValue decoded;
std::uint64_t unsignedValue = 0U;
if (!IsValidDefinition(signal, dlc) ||
(signal.multiplexing.role != MultiplexRole::Unconditional && !selector.valid)) {
if (!IsValidDefinition(signal, dlc))
return decoded;
if (activation != SignalDecodeStatus::Valid) {
decoded.status = activation;
return decoded;
}
if (signal.multiplexing.role == MultiplexRole::Branch) {
if (selector.definition->length < 64U && signal.multiplexing.value >= (std::uint64_t(1U) << selector.definition->length)) {
return decoded;
}
if (!selector.available) {
decoded.status = SignalDecodeStatus::SelectorUnavailable;
return decoded;
}
if (signal.multiplexing.value != selector.value) {
decoded.status = SignalDecodeStatus::Inactive;
return decoded;
}
}
if (!ExtractUnsigned(frame.data, signal, unsignedValue)) {
decoded.status = SignalDecodeStatus::InsufficientPayload;