Closes #29
This commit is contained in:
1 parent
a702cffd93
commit
8d06165979
18 files changed
+611
-215
No files matched your search
+29
-36
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user