Closes #29
This commit is contained in:
1 parent
a702cffd93
commit
8d06165979
18 files changed
+611
-215
No files matched your search
+16
-20
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "decode_database.h"
|
||||
#include "j1939.h"
|
||||
#include "multiplex_graph.h"
|
||||
#include "signal_layout.h"
|
||||
#include <bitset>
|
||||
#include <cmath>
|
||||
@@ -21,7 +22,8 @@ namespace {
|
||||
throw std::invalid_argument("Invalid signal value type: " + signal.name);
|
||||
if (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)
|
||||
throw std::invalid_argument("Invalid multiplexing role: " + signal.name);
|
||||
if (!IsValidSignalLayout(signal.startBit, signal.length,
|
||||
signal.byteOrder == ByteOrder::Intel, dlc))
|
||||
@@ -45,13 +47,7 @@ namespace {
|
||||
return bits;
|
||||
}
|
||||
|
||||
bool AreMutuallyExclusive(const DecodeSignal &first, const DecodeSignal &second) {
|
||||
return first.multiplexing.role == MultiplexRole::Branch &&
|
||||
second.multiplexing.role == MultiplexRole::Branch &&
|
||||
first.multiplexing.value != second.multiplexing.value;
|
||||
}
|
||||
|
||||
void ValidateFrame(const DecodeFrame &frame) {
|
||||
dbc_detail::MultiplexGraph ValidateFrame(const DecodeFrame &frame) {
|
||||
const std::uint32_t maximumId = frame.isExtended ? 0x1FFFFFFFU : 0x7FFU;
|
||||
if (frame.canId > maximumId)
|
||||
throw std::invalid_argument("Invalid normalized CAN ID: " + std::to_string(frame.canId));
|
||||
@@ -60,33 +56,28 @@ namespace {
|
||||
throw std::invalid_argument("Invalid J1939 PGN metadata: " + frame.name);
|
||||
|
||||
std::unordered_set<std::string> names;
|
||||
const DecodeSignal *selector = nullptr;
|
||||
|
||||
for (const DecodeSignal &signal: frame.signals) {
|
||||
if (!names.insert(signal.name).second)
|
||||
throw std::invalid_argument("Duplicate runtime signal key: " + signal.name);
|
||||
ValidateSignal(signal, frame.dlc);
|
||||
if (signal.multiplexing.role == MultiplexRole::Selector) {
|
||||
if (selector != nullptr || signal.valueType != ValueType::Unsigned)
|
||||
throw std::invalid_argument("Multiplexing requires one unsigned selector per frame");
|
||||
selector = &signal;
|
||||
}
|
||||
if (IsMultiplexSelector(signal.multiplexing.role) && signal.valueType != ValueType::Unsigned)
|
||||
throw std::invalid_argument("Multiplex selectors must be unsigned.");
|
||||
}
|
||||
const dbc_detail::MultiplexGraph graph(frame.signals);
|
||||
|
||||
std::vector<SignalBits> layouts;
|
||||
layouts.reserve(frame.signals.size());
|
||||
for (std::size_t index = 0U; index < frame.signals.size(); ++index) {
|
||||
const DecodeSignal &signal = frame.signals[index];
|
||||
if (signal.multiplexing.role == MultiplexRole::Branch &&
|
||||
(selector == nullptr ||
|
||||
(selector->length < 64U && signal.multiplexing.value >= (std::uint64_t(1U) << selector->length))))
|
||||
throw std::invalid_argument("Missing selector or branch value outside selector range: " + signal.name);
|
||||
const SignalBits bits = GetSignalBits(signal);
|
||||
for (std::size_t previous = 0U; previous < index; ++previous) {
|
||||
if (!AreMutuallyExclusive(signal, frame.signals[previous]) && (bits & layouts[previous]).any())
|
||||
if (!graph.AreMutuallyExclusive(index, previous) && (bits & layouts[previous]).any())
|
||||
throw std::invalid_argument("Overlapping signals: " + signal.name);
|
||||
}
|
||||
layouts.push_back(bits);
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
}// namespace
|
||||
|
||||
@@ -95,8 +86,9 @@ DecodeDatabase::Storage::Storage(const std::vector<DecodeFrame> &definitions)
|
||||
// Validate the complete snapshot before creating its lookup index.
|
||||
std::unordered_set<FrameKey, FrameKeyHasher> keys;
|
||||
keys.reserve(frames.size());
|
||||
multiplexGraphs.reserve(frames.size());
|
||||
for (const DecodeFrame &frame: frames) {
|
||||
ValidateFrame(frame);
|
||||
multiplexGraphs.push_back(ValidateFrame(frame));
|
||||
if (!keys.insert(frame.GetKey()).second)
|
||||
throw std::invalid_argument("Duplicate runtime frame key");
|
||||
}
|
||||
@@ -153,3 +145,7 @@ std::shared_ptr<const DecodeSignal> DecodeDatabase::FindSignal(const SignalKey &
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const dbc_detail::MultiplexGraph &DecodeDatabase::GetMultiplexGraph(const FrameKey &key) const {
|
||||
return storage->multiplexGraphs[storage->frameIndexByKey.at(key)];
|
||||
}
|
||||
Reference in new issue
Block a user