This commit is contained in:
deeaitch committed 2026-10-13 08:05:40 -04:00
1 parent 0708316a37
commit 7022c84941
69 files changed
+2696 -1912

No files matched your search

+31 -3
View File
@@ -10,6 +10,7 @@
*/
#include "dbc_decoder.h"
#include <cmath>
#include <utility>
std::shared_ptr<const DecodeFrame> DbcDecoder::FindFrame(const DecodeDatabase &database,
@@ -29,11 +30,17 @@ DecodedFrameValue DbcDecoder::Decode(const DecodeDatabase &database,
result.definition = definition;
result.valid = true;
result.status = frame.data.size() < definition->dlc
? FrameDecodeStatus::InsufficientPayload
: FrameDecodeStatus::Valid;
const SelectorState selector = ReadSelector(*definition, frame);
result.signals.reserve(definition->signals.size());
for (const DecodeSignal &signal: definition->signals) {
DecodedSignalValue decoded = DecodeOneSignal(signal, frame, selector);
DecodedSignalValue decoded = DecodeOneSignal(signal, definition->dlc, frame, selector);
if (!decoded.valid && decoded.status != SignalDecodeStatus::Inactive &&
result.status == FrameDecodeStatus::Valid)
result.status = FrameDecodeStatus::SignalErrors;
decoded.definition = std::shared_ptr<const DecodeSignal>(definition, &signal);
decoded.key = SignalKey(result.key, signal.name);
result.signals.push_back(std::move(decoded));
@@ -42,6 +49,22 @@ DecodedFrameValue DbcDecoder::Decode(const DecodeDatabase &database,
return result;
}
bool DbcDecoder::IsValidDefinition(const DecodeSignal &signal, std::uint8_t dlc) {
if (signal.length == 0U || signal.length > 64U ||
(signal.byteOrder != ByteOrder::Intel && signal.byteOrder != ByteOrder::Motorola) ||
(signal.valueType != ValueType::Unsigned && signal.valueType != ValueType::Signed) ||
(signal.multiplexing.role != MultiplexRole::Unconditional &&
signal.multiplexing.role != MultiplexRole::Selector &&
signal.multiplexing.role != MultiplexRole::Branch))
return false;
// Use widened coordinates to avoid overflow on malformed start bits.
const std::uint64_t start = signal.byteOrder == ByteOrder::Intel
? signal.startBit
: std::uint64_t(signal.startBit / 8U) * 8U + 7U - signal.startBit % 8U;
return start + signal.length <= std::uint64_t(dlc) * 8U;
}
DbcDecoder::SelectorState DbcDecoder::ReadSelector(const DecodeFrame &definition,
const RawCanFrame &frame) {
SelectorState selector;
@@ -57,18 +80,19 @@ DbcDecoder::SelectorState DbcDecoder::ReadSelector(const DecodeFrame &definition
const DecodeSignal &signal = *selector.definition;
selector.valid = signal.valueType == ValueType::Unsigned &&
signal.length > 0U && signal.length <= 64U;
IsValidDefinition(signal, definition.dlc);
selector.available = selector.valid && ExtractUnsigned(frame.data, signal, selector.value);
return selector;
}
DecodedSignalValue DbcDecoder::DecodeOneSignal(const DecodeSignal &signal,
std::uint8_t dlc,
const RawCanFrame &frame,
const SelectorState &selector) {
DecodedSignalValue decoded;
std::uint64_t unsignedValue = 0U;
if (signal.length == 0U || signal.length > 64U ||
if (!IsValidDefinition(signal, dlc) ||
(signal.multiplexing.role != MultiplexRole::Unconditional && !selector.valid)) {
return decoded;
}
@@ -101,6 +125,10 @@ DecodedSignalValue DbcDecoder::DecodeOneSignal(const DecodeSignal &signal,
else
numericValue = static_cast<double>(std::get<std::uint64_t>(decoded.rawValue));
decoded.physicalValue = numericValue * signal.factor + signal.offset;
if (!std::isfinite(decoded.physicalValue)) {
decoded.status = SignalDecodeStatus::PhysicalConversionFailed;
return decoded;
}
decoded.valid = true;
decoded.status = SignalDecodeStatus::Valid;