Closes #15
This commit is contained in:
1 parent
0708316a37
commit
7022c84941
69 files changed
+2696
-1912
No files matched your search
+31
-3
@@ -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;
|
||||
|
||||
|
||||
+16
-2
@@ -34,6 +34,15 @@ enum class SignalDecodeStatus {
|
||||
InsufficientPayload,
|
||||
SelectorUnavailable,
|
||||
Inactive,
|
||||
Valid,
|
||||
PhysicalConversionFailed
|
||||
};
|
||||
|
||||
/** Frame summary: short payload takes precedence over individual signal errors. */
|
||||
enum class FrameDecodeStatus {
|
||||
UnknownFrame,
|
||||
InsufficientPayload,
|
||||
SignalErrors,
|
||||
Valid
|
||||
};
|
||||
|
||||
@@ -43,8 +52,8 @@ enum class SignalDecodeStatus {
|
||||
struct DecodedSignalValue {
|
||||
std::shared_ptr<const DecodeSignal> definition; /**< Owning immutable definition. */
|
||||
SignalKey key; /**< Stable application identifier. */
|
||||
RawSignalValue rawValue = std::uint64_t(0U); /**< Exact signed or unsigned raw value. */
|
||||
double physicalValue = 0.0; /**< Converted physical value. */
|
||||
RawSignalValue rawValue = std::uint64_t(0U); /**< Exact raw value for Valid or PhysicalConversionFailed. */
|
||||
double physicalValue = 0.0; /**< Conversion result, possibly NaN/Inf on failure. */
|
||||
bool valid = false; /**< true if decoding succeeded. */
|
||||
SignalDecodeStatus status = SignalDecodeStatus::InvalidDefinition;
|
||||
|
||||
@@ -64,6 +73,7 @@ struct DecodedFrameValue {
|
||||
FrameKey key; /**< Stable application identifier. */
|
||||
std::vector<DecodedSignalValue> signals; /**< Decoded signal values. */
|
||||
bool valid = false; /**< true if frame was matched. */
|
||||
FrameDecodeStatus status = FrameDecodeStatus::UnknownFrame; /**< Inspect signals for individual failures. */
|
||||
|
||||
DecodedFrameValue() = default;
|
||||
};
|
||||
@@ -88,12 +98,15 @@ public:
|
||||
* @brief Decode one raw CAN frame.
|
||||
* @param database Runtime decode database.
|
||||
* @param frame Raw CAN frame.
|
||||
* Short payloads decode available signals; bytes beyond declared DLC are ignored.
|
||||
* @return Decoded frame value.
|
||||
*/
|
||||
DecodedFrameValue Decode(const DecodeDatabase &database,
|
||||
const RawCanFrame &frame) const;
|
||||
|
||||
private:
|
||||
static bool IsValidDefinition(const DecodeSignal &signal, std::uint8_t dlc);
|
||||
|
||||
struct SelectorState {
|
||||
const DecodeSignal *definition = nullptr;
|
||||
bool valid = false;
|
||||
@@ -103,6 +116,7 @@ private:
|
||||
|
||||
static SelectorState ReadSelector(const DecodeFrame &definition, const RawCanFrame &frame);
|
||||
static DecodedSignalValue DecodeOneSignal(const DecodeSignal &signal,
|
||||
std::uint8_t dlc,
|
||||
const RawCanFrame &frame,
|
||||
const SelectorState &selector);
|
||||
|
||||
|
||||
Reference in new issue
Block a user