Add management of version and new decoder signature. 65/22265/2 8.99.1 8.99.2 8.99.3 8.99.4 8.99.5 9.99.1 9.99.2 9.99.3 9.99.4 icefish/8.99.1 icefish/8.99.2 icefish/8.99.3 icefish/8.99.4 icefish/8.99.5 icefish_8.99.1 icefish_8.99.2 icefish_8.99.3 icefish_8.99.4 icefish_8.99.5 jellyfish/9.99.1 jellyfish/9.99.2 jellyfish/9.99.3 jellyfish/9.99.4 jellyfish_9.99.1 jellyfish_9.99.2 jellyfish_9.99.3 jellyfish_9.99.4
authorArthur Guyader <arthur.guyader@iot.bzh>
Thu, 29 Aug 2019 13:10:39 +0000 (15:10 +0200)
committerArthur Guyader <arthur.guyader@iot.bzh>
Thu, 29 Aug 2019 16:10:56 +0000 (18:10 +0200)
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

Change-Id: I169d5a8213d6a14e5d77b600e14b36f0878b3efe
Signed-off-by: Arthur Guyader <arthur.guyader@iot.bzh>
src/CMakeLists.txt
src/main.cpp
src/openxc/decoder.cpp [new file with mode: 0644]
src/openxc/decoder.hpp [new file with mode: 0644]
src/openxc/message_set.cpp
src/openxc/message_set.hpp

index 2824b71..5da7e6e 100644 (file)
@@ -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
index b35f9e3..c001df3 100644 (file)
@@ -27,6 +27,7 @@
 #include <iterator>\r
 #include <json.hpp>\r
 #include "openxc/message_set.hpp"\r
+#include "openxc/decoder.hpp"\r
 \r
 #define EXIT_SUCCESS                           0\r
 #define EXIT_UNKNOWN_ERROR                     1\r
 #define ISOTP_PROTOCOL 0x0040\r
 #define FD_FRAME 0x0800\r
 \r
+#define VERSION_LOW_CAN "2.0"\r
+\r
+\r
+std::string VERSION_FILE = "1.0";\r
+\r
 template <typename T>\r
 struct generator\r
 {\r
@@ -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"\r
                << gen(v.v_.states(), v.line_prefix_ + '\t') << ",// states\n"\r
                << v.line_prefix_ << '\t' << gen(v.v_.writable()) << ",// writable\n"\r
-               << v.line_prefix_ << '\t' << (v.v_.decoder().size() ? v.v_.decoder() : v.v_.states().size() ? "decoder_t::decode_state" : "nullptr") << ",// decoder\n"\r
+               << v.line_prefix_ << '\t' << decoder_t::add_decoder(v.v_.decoder().size() ? v.v_.decoder() : v.v_.states().size() ? "decoder_t::decode_state" : "nullptr"\r
+                       , VERSION_FILE\r
+                       , VERSION_LOW_CAN) << ",// decoder\n"\r
                << v.line_prefix_ << '\t' << (v.v_.encoder().size() ? v.v_.encoder() : "nullptr") << ",// encoder\n"\r
                << v.line_prefix_ << '\t' << "false,// received\n";\r
                std::string multi_first = "";\r
@@ -260,7 +268,7 @@ std::ostream& operator<<(std::ostream& o, const generator<openxc::diagnostic_mes
                << v.line_prefix_ << "\t" << 0 << ",\n"\r
                << v.line_prefix_ << "\t" << "UNIT::INVALID" << ",\n"\r
                << v.line_prefix_ << "\t" << gen(v.v_.frequency()) << ",\n"\r
-               << v.line_prefix_ << "\t" << (v.v_.decoder().size() ? v.v_.decoder() : "nullptr") << ",\n"\r
+               << v.line_prefix_ << "\t" << decoder_t::add_decoder((v.v_.decoder().size() ? v.v_.decoder() : "nullptr"),VERSION_FILE,VERSION_LOW_CAN) << ",\n"\r
                << v.line_prefix_ << "\t" << (v.v_.callback().size() ? v.v_.callback() : "nullptr") << ",\n"\r
                << v.line_prefix_ << "\t" << "true" << ",\n"\r
                << v.line_prefix_ << "\t" << "false" << "\n"\r
@@ -319,6 +327,12 @@ void generate(const std::string& header, const std::string& footer, const openxc
 \r
        out     << "\treturn " << gen(active_bus) << ";\n"\r
                << "}\n\n";\r
+\r
+\r
+       out << decoder_t::apply_patch();\r
+\r
+\r
+\r
        out     << footer << std::endl;\r
 }\r
 \r
@@ -379,6 +393,8 @@ std::cout<<"         "<<"-o application-generated.cpp : output source file. Name
 /// @return Exit code, zero if success.\r
 int main(int argc, char *argv[])\r
 {\r
+\r
+       decoder_t::init_decoder();\r
        try\r
        {\r
                std::string appName = argv[0];\r
@@ -445,6 +461,7 @@ int main(int argc, char *argv[])
                                throw std::runtime_error(ss.str());\r
                        }\r
                }\r
+               VERSION_FILE = message_set.version();\r
                generate(header.str(), footer, message_set, output_file.size() ? out : std::cout);\r
        }\r
        catch (std::exception& e)\r
diff --git a/src/openxc/decoder.cpp b/src/openxc/decoder.cpp
new file mode 100644 (file)
index 0000000..c8846e8
--- /dev/null
@@ -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 (file)
index 0000000..719b609
--- /dev/null
@@ -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);
+};
index d6745bf..7fd7e9d 100755 (executable)
@@ -5,6 +5,7 @@ namespace openxc
 {\r
        message_set::message_set()\r
                : name_{""}\r
+               , version_{"1.0"}\r
                , bit_numbering_inverted_{false}\r
                , max_message_frequency_{0}\r
                , raw_can_mode_{can_bus_mode::off}\r
@@ -19,67 +20,72 @@ namespace openxc
                , commands_{}\r
        {\r
        }\r
-       \r
+\r
        std::string message_set::name() const\r
        {\r
                return name_;\r
        }\r
-       \r
+\r
+       std::string message_set::version() const\r
+       {\r
+               return version_;\r
+       }\r
+\r
        bool message_set::bit_numbering_inverted() const\r
        {\r
                return bit_numbering_inverted_;\r
        }\r
-       \r
+\r
        float message_set::max_message_frequency() const\r
        {\r
                return max_message_frequency_;\r
        }\r
-       \r
+\r
        can_bus_mode message_set::raw_can_mode() const\r
        {\r
                return raw_can_mode_;\r
        }\r
-       \r
+\r
        const std::vector<std::string>& message_set::parents() const\r
        {\r
                return parents_;\r
        }\r
-       \r
+\r
        const std::vector<std::string>& message_set::initializers() const\r
        {\r
                return initializers_;\r
        }\r
-       \r
+\r
        const std::vector<std::string>& message_set::loopers() const\r
        {\r
                return loopers_;\r
        }\r
-       \r
+\r
        const std::map<std::string, can_bus>& message_set::buses() const\r
        {\r
                return buses_;\r
        }\r
-       \r
+\r
        const std::vector<can_message>& message_set::messages() const\r
        {\r
                return messages_;\r
        }\r
-       \r
+\r
        const std::vector<diagnostic_message>& message_set::diagnostic_messages() const\r
        {\r
                return diagnostic_messages_;\r
        }\r
-       \r
+\r
        const std::vector<mapping>& message_set::mappings() const\r
        {\r
                return mappings_;\r
        }\r
-       \r
+\r
        const std::vector<std::string>& message_set::extra_sources() const\r
        {\r
                return extra_sources_;\r
        }\r
-       \r
+\r
        const std::vector<command>& message_set::commands() const\r
        {\r
                return commands_;\r
@@ -88,6 +94,7 @@ namespace openxc
        void message_set::from_json(const nlohmann::json& j)\r
        {\r
                name_ = j["name"].get<std::string>();\r
+               version_ = j["version"].get<std::string>();\r
                bit_numbering_inverted_ = j.count("bit_numbering_inverted") ? j["bit_numbering_inverted"].get<bool>() : false; // TODO: should be true by default if database-backed.\r
                max_message_frequency_ = j.count("max_message_frequency") ? j["max_message_frequency"].get<float>() : 0.0f;\r
                raw_can_mode_ = j.count("raw_can_mode") ? j["raw_can_mode"].get<can_bus_mode>() : can_bus_mode::off;\r
@@ -100,8 +107,8 @@ namespace openxc
                mappings_ = j.count("mappings") ? j["mappings"].get<std::vector<mapping>>() : std::vector<mapping>();\r
                extra_sources_ = j.count("extra_sources") ? j["extra_sources"].get<std::vector<std::string>>() : std::vector<std::string>();\r
                commands_ = j.count("commands") ? j["commands"].get<std::vector<command>>() : std::vector<command>();\r
-               \r
-               \r
+\r
+\r
                if (j.count("messages"))\r
                {\r
                        std::map<std::string, nlohmann::json> messages = j["messages"];\r
@@ -117,7 +124,8 @@ namespace openxc
        nlohmann::json message_set::to_json() const\r
        {\r
                nlohmann::json j;\r
-               j["name_"]                                              = name_;\r
+               j["name"]                                               = name_;\r
+               j["version"]                                    = version_;\r
                j["bit_numbering_inverted"]             = bit_numbering_inverted_;\r
                j["max_message_frequency"]              = max_message_frequency_;\r
                j["raw_can_mode"]                               = raw_can_mode_;\r
index 935817e..fa919ae 100755 (executable)
@@ -17,6 +17,7 @@ namespace openxc
        {\r
        private:\r
                std::string                                                     name_;\r
+               std::string                                                     version_;\r
                bool                                                            bit_numbering_inverted_;\r
                float                                                           max_message_frequency_;\r
                can_bus_mode                                            raw_can_mode_;\r
@@ -35,8 +36,9 @@ namespace openxc
                message_set();\r
                message_set(const message_set&) = default;\r
                message_set(message_set&&) = default;\r
-               \r
+\r
                std::string name() const;\r
+               std::string version() const;\r
                bool bit_numbering_inverted() const;\r
                float max_message_frequency() const;\r
                can_bus_mode raw_can_mode() const;\r
@@ -49,7 +51,7 @@ namespace openxc
                const std::vector<mapping>& mappings() const;\r
                const std::vector<std::string>& extra_sources() const;\r
                const std::vector<command>& commands() const;\r
-               \r
+\r
                void from_json(const nlohmann::json& j);\r
                nlohmann::json to_json() const;\r
        };\r