Closes #28
This commit is contained in:
1 parent
a0938cb29c
commit
3dd9230fca
21 files changed
+491
-450
No files matched your search
+70
-63
@@ -39,73 +39,80 @@ DecodedFrameValue DbcDecoder::Decode(const DecodeDatabase &database,
|
||||
result.definition = definition;
|
||||
result.valid = true;
|
||||
|
||||
const DecodeSignal *selector = nullptr;
|
||||
std::size_t selectorCount = 0U;
|
||||
for (const DecodeSignal &signal : definition->signals) {
|
||||
if (signal.multiplexing.role == MultiplexRole::Selector) {
|
||||
selector = &signal;
|
||||
++selectorCount;
|
||||
}
|
||||
}
|
||||
const bool selectorDefinitionValid = selectorCount == 1U &&
|
||||
selector->valueType == ValueType::Unsigned && selector->length > 0U && selector->length <= 64U;
|
||||
std::uint64_t selectorValue = 0U;
|
||||
const bool selectorAvailable = selectorDefinitionValid && ExtractUnsigned(frame.data, *selector, selectorValue);
|
||||
|
||||
for (std::size_t signalIndex = 0U; signalIndex < definition->signals.size(); ++signalIndex) {
|
||||
const DecodeSignal &signal = definition->signals[signalIndex];
|
||||
DecodedSignalValue decoded;
|
||||
std::uint64_t unsignedValue = 0U;
|
||||
|
||||
decoded.definition = &signal;
|
||||
|
||||
if (signal.length == 0U || signal.length > 64U ||
|
||||
(signal.multiplexing.role != MultiplexRole::Unconditional && !selectorDefinitionValid)) {
|
||||
result.signals.push_back(decoded);
|
||||
continue;
|
||||
}
|
||||
if (signal.multiplexing.role == MultiplexRole::Branch) {
|
||||
if (selector->length < 64U && signal.multiplexing.value >= (std::uint64_t(1U) << selector->length)) {
|
||||
result.signals.push_back(decoded);
|
||||
continue;
|
||||
}
|
||||
if (!selectorAvailable) {
|
||||
decoded.status = SignalDecodeStatus::SelectorUnavailable;
|
||||
result.signals.push_back(decoded);
|
||||
continue;
|
||||
}
|
||||
if (signal.multiplexing.value != selectorValue) {
|
||||
decoded.status = SignalDecodeStatus::Inactive;
|
||||
result.signals.push_back(decoded);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!ExtractUnsigned(frame.data, signal, unsignedValue)) {
|
||||
decoded.status = SignalDecodeStatus::InsufficientPayload;
|
||||
result.signals.push_back(decoded);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (signal.valueType == ValueType::Signed)
|
||||
decoded.rawValue = SignExtend(unsignedValue, signal.length);
|
||||
else
|
||||
decoded.rawValue = unsignedValue;
|
||||
|
||||
double numericValue;
|
||||
if (const std::int64_t *signedValue = std::get_if<std::int64_t>(&decoded.rawValue))
|
||||
numericValue = static_cast<double>(*signedValue);
|
||||
else
|
||||
numericValue = static_cast<double>(std::get<std::uint64_t>(decoded.rawValue));
|
||||
decoded.physicalValue = numericValue * signal.factor + signal.offset;
|
||||
decoded.valid = true;
|
||||
decoded.status = SignalDecodeStatus::Valid;
|
||||
|
||||
result.signals.push_back(decoded);
|
||||
}
|
||||
const SelectorState selector = ReadSelector(*definition, frame);
|
||||
for (const DecodeSignal &signal : definition->signals)
|
||||
result.signals.push_back(DecodeOneSignal(signal, frame, selector));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (count != 1U)
|
||||
return selector;
|
||||
|
||||
const DecodeSignal &signal = *selector.definition;
|
||||
selector.valid = signal.valueType == ValueType::Unsigned &&
|
||||
signal.length > 0U && signal.length <= 64U;
|
||||
selector.available = selector.valid && ExtractUnsigned(frame.data, signal, selector.value);
|
||||
return selector;
|
||||
}
|
||||
|
||||
DecodedSignalValue DbcDecoder::DecodeOneSignal(const DecodeSignal &signal,
|
||||
const RawCanFrame &frame,
|
||||
const SelectorState &selector) {
|
||||
DecodedSignalValue decoded;
|
||||
std::uint64_t unsignedValue = 0U;
|
||||
|
||||
decoded.definition = &signal;
|
||||
|
||||
if (signal.length == 0U || signal.length > 64U ||
|
||||
(signal.multiplexing.role != MultiplexRole::Unconditional && !selector.valid)) {
|
||||
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;
|
||||
return decoded;
|
||||
}
|
||||
|
||||
if (signal.valueType == ValueType::Signed)
|
||||
decoded.rawValue = SignExtend(unsignedValue, signal.length);
|
||||
else
|
||||
decoded.rawValue = unsignedValue;
|
||||
|
||||
double numericValue;
|
||||
if (const std::int64_t *signedValue = std::get_if<std::int64_t>(&decoded.rawValue))
|
||||
numericValue = static_cast<double>(*signedValue);
|
||||
else
|
||||
numericValue = static_cast<double>(std::get<std::uint64_t>(decoded.rawValue));
|
||||
decoded.physicalValue = numericValue * signal.factor + signal.offset;
|
||||
decoded.valid = true;
|
||||
decoded.status = SignalDecodeStatus::Valid;
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
bool DbcDecoder::ExtractUnsigned(const std::vector<std::uint8_t> &data,
|
||||
const DecodeSignal &signal,
|
||||
std::uint64_t &value) {
|
||||
|
||||
Reference in new issue
Block a user