summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Forlot <romain.forlot@iot.bzh>2019-11-26 16:07:15 +0100
committerRomain Forlot <romain.forlot@iot.bzh>2019-11-26 16:07:15 +0100
commit0d65a0be7d834b23de99e73bba5407185f54aeca (patch)
treed97480eb71cf39a13d7c89a297ff5a3b9aaa5bfb
parent839bbf458685383634c03e8cec2238f70c6f0382 (diff)
This commit allows to generate a file according to the version. And adds the wrapper function for new decoder between v1 and v2. Bug-AGL: SPEC-2780 Bug-AGL: SPEC-2976 Change-Id: I169d5a8213d6a14e5d77b600e14b36f0878b3efe Signed-off-by: Arthur Guyader <arthur.guyader@iot.bzh> Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/main.cpp21
-rw-r--r--src/openxc/decoder.cpp108
-rw-r--r--src/openxc/decoder.hpp28
-rwxr-xr-xsrc/openxc/message_set.cpp40
-rwxr-xr-xsrc/openxc/message_set.hpp6
6 files changed, 186 insertions, 21 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2824b71..5da7e6e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,7 +28,9 @@ add_executable(${TARGET_NAME}
openxc/command.cpp
openxc/diagnostic_message.cpp
openxc/mapping.cpp
- openxc/signal.cpp)
+ openxc/signal.cpp
+ openxc/decoder.cpp
+ )
TARGET_INCLUDE_DIRECTORIES(${TARGET_NAME}
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/json
diff --git a/src/main.cpp b/src/main.cpp
index b35f9e3..c001df3 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -27,6 +27,7 @@
#include <iterator>
#include <json.hpp>
#include "openxc/message_set.hpp"
+#include "openxc/decoder.hpp"
#define EXIT_SUCCESS 0
#define EXIT_UNKNOWN_ERROR 1
@@ -47,6 +48,11 @@
#define ISOTP_PROTOCOL 0x0040
#define FD_FRAME 0x0800
+#define VERSION_LOW_CAN "2.0"
+
+
+std::string VERSION_FILE = "1.0";
+
template <typename T>
struct generator
{
@@ -173,7 +179,9 @@ std::ostream& operator<<(std::ostream& o, const generator<openxc::signal>& v)
<< v.line_prefix_ << "\t" << gen(v.v_.force_send_changed()) << ",// force_send_changed\n"
<< gen(v.v_.states(), v.line_prefix_ + '\t') << ",// states\n"
<< v.line_prefix_ << '\t' << gen(v.v_.writable()) << ",// writable\n"
- << v.line_prefix_ << '\t' << (v.v_.decoder().size() ? v.v_.decoder() : v.v_.states().size() ? "decoder_t::decode_state" : "nullptr") << ",// decoder\n"
+ << v.line_prefix_ << '\t' << decoder_t::add_decoder(v.v_.decoder().size() ? v.v_.decoder() : v.v_.states().size() ? "decoder_t::decode_state" : "nullptr"
+ , VERSION_FILE
+ , VERSION_LOW_CAN) << ",// decoder\n"
<< v.line_prefix_ << '\t' << (v.v_.encoder().size() ? v.v_.encoder() : "nullptr") << ",// encoder\n"
<< v.line_prefix_ << '\t' << "false,// received\n";
std::string multi_first = "";
@@ -260,7 +268,7 @@ std::ostream& operator<<(std::ostream& o, const generator<openxc::diagnostic_mes
<< v.line_prefix_ << "\t" << 0 << ",\n"
<< v.line_prefix_ << "\t" << "UNIT::INVALID" << ",\n"
<< v.line_prefix_ << "\t" << gen(v.v_.frequency()) << ",\n"
- << v.line_prefix_ << "\t" << (v.v_.decoder().size() ? v.v_.decoder() : "nullptr") << ",\n"
+ << v.line_prefix_ << "\t" << decoder_t::add_decoder((v.v_.decoder().size() ? v.v_.decoder() : "nullptr"),VERSION_FILE,VERSION_LOW_CAN) << ",\n"
<< v.line_prefix_ << "\t" << (v.v_.callback().size() ? v.v_.callback() : "nullptr") << ",\n"
<< v.line_prefix_ << "\t" << "true" << ",\n"
<< v.line_prefix_ << "\t" << "false" << "\n"
@@ -319,6 +327,12 @@ void generate(const std::string& header, const std::string& footer, const openxc
out << "\treturn " << gen(active_bus) << ";\n"
<< "}\n\n";
+
+
+ out << decoder_t::apply_patch();
+
+
+
out << footer << std::endl;
}
@@ -379,6 +393,8 @@ std::cout<<" "<<"-o application-generated.cpp : output source file. Name
/// @return Exit code, zero if success.
int main(int argc, char *argv[])
{
+
+ decoder_t::init_decoder();
try
{
std::string appName = argv[0];
@@ -445,6 +461,7 @@ int main(int argc, char *argv[])
throw std::runtime_error(ss.str());
}
}
+ VERSION_FILE = message_set.version();
generate(header.str(), footer, message_set, output_file.size() ? out : std::cout);
}
catch (std::exception& e)
diff --git a/src/openxc/decoder.cpp b/src/openxc/decoder.cpp
new file mode 100644
index 0000000..c8846e8
--- /dev/null
+++ b/src/openxc/decoder.cpp
@@ -0,0 +1,108 @@
+#include "decoder.hpp"
+
+map_decoders decoder_t::decoders_states_;
+std::string decoder_t::patchs_;
+
+
+void decoder_t::init_decoder()
+{
+ decoder_t::decoders_states_.insert(pair_decoder("decode_state", states::NATIVE));
+ decoder_t::decoders_states_.insert(pair_decoder("decode_boolean", states::NATIVE));
+ decoder_t::decoders_states_.insert(pair_decoder("decode_ignore", states::NATIVE));
+ decoder_t::decoders_states_.insert(pair_decoder("decode_noop", states::NATIVE));
+ decoder_t::decoders_states_.insert(pair_decoder("decode_bytes", states::NATIVE));
+ decoder_t::decoders_states_.insert(pair_decoder("decode_obd2_response", states::NATIVE));
+}
+
+
+std::string decoder_t::add_decoder(std::string decoder, std::string version_file, std::string version_low_can)
+{
+ if(decoder.compare("nullptr"))
+ {
+ std::string key = "decoder_t::";
+ std::size_t pos = decoder.find(key);
+ std::string decoder_split = decoder.substr(pos+key.size()); // only name of decoder
+
+ if ( decoder_t::decoders_states_.find(decoder_split) == decoder_t::decoders_states_.end() ) { // Not found signal
+ decoder_t::decoders_states_.insert(pair_decoder(decoder_split,states::NEW));
+ std::string ret = key + decoder_t::patch_version(decoder_split,version_file,version_low_can);
+ decoder_t::decoders_states_[decoder_split] = states::PROCESSED;
+ return ret;
+ }
+ else
+ {
+ if(decoder_t::decoders_states_[decoder_split] == states::PROCESSED)
+ {
+ return key + decoder_t::patch_version(decoder_split,version_file,version_low_can);
+ }
+ }
+ }
+ return decoder;
+}
+
+
+std::string decoder_t::patch_version(std::string decoder, std::string version_file, std::string version_low_can)
+{
+ std::size_t pos = version_file.find(".");
+ int main_value_version_file = std::stoi(version_file.substr(0,pos));
+
+ std::size_t pos2 = version_low_can.find(".");
+ int main_value_version_low_can = std::stoi(version_low_can.substr(0,pos2));
+
+ if(main_value_version_file != main_value_version_low_can) // Not same version
+ {
+ if(decoder_t::decoders_states_[decoder] == states::NEW)
+ {
+ if(main_value_version_low_can == 2)
+ {
+ if(main_value_version_file == 1)
+ {
+ decoder_t::v1_to_v2(decoder); // add wrap
+ }
+ else
+ {
+ throw "Version not implemented";
+ }
+ }
+ else
+ {
+ throw "Version not implemented";
+ }
+ }
+ return decoder_t::generate_name_decoder(decoder,version_file,version_low_can);
+ }
+ else
+ {
+ return decoder;
+ }
+}
+
+std::string decoder_t::generate_name_decoder(std::string decoder, std::string version_file, std::string version_low_can)
+{
+ std::size_t pos = version_file.find(".");
+ std::string main_value_version_file = version_file.substr(0,pos);
+ std::size_t pos2 = version_low_can.find(".");
+ std::string main_value_version_low_can = version_low_can.substr(0,pos2);
+ return "v"+main_value_version_file+"_to_v"+main_value_version_low_can+"_"+decoder;
+}
+
+std::string decoder_t::apply_patch()
+{
+ return decoder_t::patchs_;
+}
+
+void decoder_t::v1_to_v2(std::string decoder)
+{
+ std::string patch = "";
+ patch = patch + "openxc_DynamicField decoder_t::v1_to_v2_"+decoder+"(signal_t& signal, std::shared_ptr<message_t> message, bool* send){\n";
+ patch = patch + "\tfloat value = decoder_t::parse_signal_bitfield(signal, message);\n";
+ patch = patch + "\topenxc_DynamicField ret = decoder_t::"+decoder+"(signal, value, send);\n";
+ patch = patch + "\tif ((signal.get_last_value() == value && !signal.get_send_same()) || !*send ){\n";
+ patch = patch + "\t\t*send = false;\n";
+ patch = patch + "\t}\n";
+ patch = patch + "\tsignal.set_last_value(value);\n";
+ patch = patch + "\treturn ret;\n";
+ patch = patch + "}\n";
+
+ decoder_t::patchs_ = decoder_t::patchs_ + "\n" + patch;
+} \ No newline at end of file
diff --git a/src/openxc/decoder.hpp b/src/openxc/decoder.hpp
new file mode 100644
index 0000000..719b609
--- /dev/null
+++ b/src/openxc/decoder.hpp
@@ -0,0 +1,28 @@
+#include <string>
+#include <map>
+#include <iostream>
+
+enum class states
+{
+ NATIVE,
+ NEW,
+ PROCESSED
+};
+
+typedef std::map<std::string, states> map_decoders;
+typedef std::pair<std::string,states> pair_decoder;
+
+class decoder_t
+{
+ public:
+ static std::string patchs_;
+ static map_decoders decoders_states_;
+ static void init_decoder();
+ static std::string add_decoder(std::string decoder, std::string version_file, std::string version_low_can);
+ static std::string patch_version(std::string decoder, std::string version_file, std::string version_low_can);
+ static std::string generate_name_decoder(std::string decoder, std::string version_file, std::string version_low_can);
+ static std::string apply_patch();
+
+
+ static void v1_to_v2(std::string decoder);
+};
diff --git a/src/openxc/message_set.cpp b/src/openxc/message_set.cpp
index d6745bf..7fd7e9d 100755
--- a/src/openxc/message_set.cpp
+++ b/src/openxc/message_set.cpp
@@ -5,6 +5,7 @@ namespace openxc
{
message_set::message_set()
: name_{""}
+ , version_{"1.0"}
, bit_numbering_inverted_{false}
, max_message_frequency_{0}
, raw_can_mode_{can_bus_mode::off}
@@ -19,67 +20,72 @@ namespace openxc
, commands_{}
{
}
-
+
std::string message_set::name() const
{
return name_;
}
-
+
+ std::string message_set::version() const
+ {
+ return version_;
+ }
+
bool message_set::bit_numbering_inverted() const
{
return bit_numbering_inverted_;
}
-
+
float message_set::max_message_frequency() const
{
return max_message_frequency_;
}
-
+
can_bus_mode message_set::raw_can_mode() const
{
return raw_can_mode_;
}
-
+
const std::vector<std::string>& message_set::parents() const
{
return parents_;
}
-
+
const std::vector<std::string>& message_set::initializers() const
{
return initializers_;
}
-
+
const std::vector<std::string>& message_set::loopers() const
{
return loopers_;
}
-
+
const std::map<std::string, can_bus>& message_set::buses() const
{
return buses_;
}
-
+
const std::vector<can_message>& message_set::messages() const
{
return messages_;
}
-
+
const std::vector<diagnostic_message>& message_set::diagnostic_messages() const
{
return diagnostic_messages_;
}
-
+
const std::vector<mapping>& message_set::mappings() const
{
return mappings_;
}
-
+
const std::vector<std::string>& message_set::extra_sources() const
{
return extra_sources_;
}
-
+
const std::vector<command>& message_set::commands() const
{
return commands_;
@@ -88,6 +94,7 @@ namespace openxc
void message_set::from_json(const nlohmann::json& j)
{
name_ = j["name"].get<std::string>();
+ version_ = j["version"].get<std::string>();
bit_numbering_inverted_ = j.count("bit_numbering_inverted") ? j["bit_numbering_inverted"].get<bool>() : false; // TODO: should be true by default if database-backed.
max_message_frequency_ = j.count("max_message_frequency") ? j["max_message_frequency"].get<float>() : 0.0f;
raw_can_mode_ = j.count("raw_can_mode") ? j["raw_can_mode"].get<can_bus_mode>() : can_bus_mode::off;
@@ -100,8 +107,8 @@ namespace openxc
mappings_ = j.count("mappings") ? j["mappings"].get<std::vector<mapping>>() : std::vector<mapping>();
extra_sources_ = j.count("extra_sources") ? j["extra_sources"].get<std::vector<std::string>>() : std::vector<std::string>();
commands_ = j.count("commands") ? j["commands"].get<std::vector<command>>() : std::vector<command>();
-
-
+
+
if (j.count("messages"))
{
std::map<std::string, nlohmann::json> messages = j["messages"];
@@ -117,7 +124,8 @@ namespace openxc
nlohmann::json message_set::to_json() const
{
nlohmann::json j;
- j["name_"] = name_;
+ j["name"] = name_;
+ j["version"] = version_;
j["bit_numbering_inverted"] = bit_numbering_inverted_;
j["max_message_frequency"] = max_message_frequency_;
j["raw_can_mode"] = raw_can_mode_;
diff --git a/src/openxc/message_set.hpp b/src/openxc/message_set.hpp
index 935817e..fa919ae 100755
--- a/src/openxc/message_set.hpp
+++ b/src/openxc/message_set.hpp
@@ -17,6 +17,7 @@ namespace openxc
{
private:
std::string name_;
+ std::string version_;
bool bit_numbering_inverted_;
float max_message_frequency_;
can_bus_mode raw_can_mode_;
@@ -35,8 +36,9 @@ namespace openxc
message_set();
message_set(const message_set&) = default;
message_set(message_set&&) = default;
-
+
std::string name() const;
+ std::string version() const;
bool bit_numbering_inverted() const;
float max_message_frequency() const;
can_bus_mode raw_can_mode() const;
@@ -49,7 +51,7 @@ namespace openxc
const std::vector<mapping>& mappings() const;
const std::vector<std::string>& extra_sources() const;
const std::vector<command>& commands() const;
-
+
void from_json(const nlohmann::json& j);
nlohmann::json to_json() const;
};