From 49fe0eec8f17698fc5f86d0abe01777af1fb2b23 Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Fri, 14 Apr 2017 13:24:07 +0200 Subject: Change directory architecture to use 2 separated projects. Each projects, binder and generator, has to be compiled separatly. CAN-binder will host high and low level binding CAN-config-generator only the generator used for low level binding. build.sh script just launch both build in their respective dir. Change-Id: Ic77932660fcca507b23a631d4e4e790f608880ae Signed-off-by: Romain Forlot --- CAN-config-generator/src/CMakeLists.txt | 41 +++ CAN-config-generator/src/main.cpp | 398 +++++++++++++++++++++ CAN-config-generator/src/main.hpp | 55 +++ CAN-config-generator/src/openxc/can_bus.cpp | 89 +++++ CAN-config-generator/src/openxc/can_bus.hpp | 42 +++ CAN-config-generator/src/openxc/can_message.cpp | 126 +++++++ CAN-config-generator/src/openxc/can_message.hpp | 49 +++ CAN-config-generator/src/openxc/command.cpp | 45 +++ CAN-config-generator/src/openxc/command.hpp | 25 ++ .../src/openxc/diagnostic_message.cpp | 80 +++++ .../src/openxc/diagnostic_message.hpp | 35 ++ CAN-config-generator/src/openxc/mapping.cpp | 59 +++ CAN-config-generator/src/openxc/mapping.hpp | 29 ++ CAN-config-generator/src/openxc/message_set.cpp | 145 ++++++++ CAN-config-generator/src/openxc/message_set.hpp | 59 +++ CAN-config-generator/src/openxc/signal.cpp | 142 ++++++++ CAN-config-generator/src/openxc/signal.hpp | 53 +++ 17 files changed, 1472 insertions(+) create mode 100644 CAN-config-generator/src/CMakeLists.txt create mode 100644 CAN-config-generator/src/main.cpp create mode 100644 CAN-config-generator/src/main.hpp create mode 100755 CAN-config-generator/src/openxc/can_bus.cpp create mode 100755 CAN-config-generator/src/openxc/can_bus.hpp create mode 100755 CAN-config-generator/src/openxc/can_message.cpp create mode 100755 CAN-config-generator/src/openxc/can_message.hpp create mode 100755 CAN-config-generator/src/openxc/command.cpp create mode 100755 CAN-config-generator/src/openxc/command.hpp create mode 100755 CAN-config-generator/src/openxc/diagnostic_message.cpp create mode 100755 CAN-config-generator/src/openxc/diagnostic_message.hpp create mode 100755 CAN-config-generator/src/openxc/mapping.cpp create mode 100755 CAN-config-generator/src/openxc/mapping.hpp create mode 100755 CAN-config-generator/src/openxc/message_set.cpp create mode 100755 CAN-config-generator/src/openxc/message_set.hpp create mode 100755 CAN-config-generator/src/openxc/signal.cpp create mode 100755 CAN-config-generator/src/openxc/signal.hpp (limited to 'CAN-config-generator/src') diff --git a/CAN-config-generator/src/CMakeLists.txt b/CAN-config-generator/src/CMakeLists.txt new file mode 100644 index 00000000..39ceba1e --- /dev/null +++ b/CAN-config-generator/src/CMakeLists.txt @@ -0,0 +1,41 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Fulup Ar Foll +# contrib: Romain Forlot +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +# Add target to project dependency list +PROJECT_TARGET_ADD(can-config-generator) + + # Define project Targets + add_executable(can-config-generator + main.cpp + openxc/message_set.cpp + openxc/can_bus.cpp + openxc/can_message.cpp + openxc/command.cpp + openxc/diagnostic_message.cpp + openxc/mapping.cpp + openxc/signal.cpp) + + # Library dependencies (include updates automatically) + TARGET_LINK_LIBRARIES(can-config-generator + ${link_libraries} + ) + + # installation directory + INSTALL(TARGETS can-config-generator +RUNTIME DESTINATION ${BINDINGS_INSTALL_DIR}) diff --git a/CAN-config-generator/src/main.cpp b/CAN-config-generator/src/main.cpp new file mode 100644 index 00000000..cfefed84 --- /dev/null +++ b/CAN-config-generator/src/main.cpp @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2015, 2016 "IoT.bzh" + * Author "Loïc Collignon" + * Author "Romain Forlot" + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "openxc/message_set.hpp" + +#define EXIT_SUCCESS 0 +#define EXIT_UNKNOWN_ERROR 1 +#define EXIT_COMMAND_LINE_ERROR 2 +#define EXIT_PROGRAM_ERROR 3 + +template +struct generator +{ + T v_; + std::string line_prefix_; + generator(T v, std::string line_prefix = "") : v_{v}, line_prefix_{line_prefix} {} +}; + +template <> +struct generator +{ + const openxc::signal& v_; + std::uint32_t index_; + std::string line_prefix_; + generator(const openxc::signal& v, std::uint32_t index, std::string line_prefix = "") + : v_{v}, index_{index}, line_prefix_{line_prefix} + { + } +}; + +template +generator gen(const T& v, std::string line_prefix = "") { return generator(v, line_prefix); } + +generator gen(const openxc::signal& v, std::uint32_t index, std::string line_prefix = "") +{ + return generator(v, index, line_prefix); +} + +template +std::ostream& operator<<(std::ostream& o, const generator& v) +{ + o << v.line_prefix_ << v.v_; + return o; +} + +template <> +std::ostream& operator<<(std::ostream& o, const generator& v) +{ + o << v.line_prefix_ << (v.v_ ? "true" : "false"); + return o; +} + +template <> +std::ostream& operator<<(std::ostream& o, const generator& v) +{ + o << v.line_prefix_ << std::showpoint << v.v_ << "f"; + return o; +} + +template <> +std::ostream& operator<<(std::ostream& o, const generator& v) +{ + o << v.line_prefix_ << '\"' << v.v_ << '\"'; + return o; +} + +template +std::ostream& operator<<(std::ostream& o, const generator>& v) +{ + o << v.line_prefix_ << "{\n"; + auto sz = v.v_.size(); + for(const T& i : v.v_) + { + o << gen(i, v.line_prefix_ + '\t'); + if (sz > 1) o << ","; + --sz; + o << '\n'; + } + o << v.line_prefix_ << '}'; + return o; +} + +template <> +std::ostream& operator<<(std::ostream& o, const generator& v) +{ + o << v.line_prefix_ + << '{' + << "0, " + << gen(v.v_.name()) << ", " + << v.v_.buses().size() << ", " + << v.v_.messages().size() << ", " + << std::accumulate( + std::begin(v.v_.messages()), + std::end(v.v_.messages()), + 0, + [](int sum, const openxc::can_message& p) { return sum + p.signals().size(); } + ) << ", " + << v.v_.commands().size() << ", " + << v.v_.diagnostic_messages().size() << "}"; + return o; +} + +template <> +std::ostream& operator<<(std::ostream& o, const generator& v) +{ + o << v.line_prefix_ + << "can_message_definition_t(" + << "0, " + << gen(v.v_.bus()) << ", " + << v.v_.id() << ", " + << "can_message_format_t::STANDARD, " + << "frequency_clock_t(" << gen(v.v_.max_frequency()) << "), " + << gen(v.v_.force_send_changed()) + << ')'; + return o; +} + +template <> +std::ostream& operator<<(std::ostream& o, const generator>>& v) +{ + o << v.line_prefix_ << "{\n"; + std::uint32_t c1 = v.v_.size(); + for(const auto& state : v.v_) + { + std::uint32_t c2 = state.second.size(); + for(const auto& i : state.second) + { + o << v.line_prefix_ << "\t" << "{" << i << ", " << gen(state.first) << "}"; + if (c1 > 1 || c2 > 1) o << ','; + o << '\n'; + --c2; + } + --c1; + } + o << v.line_prefix_ << "}"; + return o; +} + +template <> +std::ostream& operator<<(std::ostream& o, const generator& v) +{ + o << v.line_prefix_ << "{\n" + << v.line_prefix_ << "\t0,\n" + << v.line_prefix_ << "\t" << v.index_ << ",\n" + << v.line_prefix_ << "\t" << gen(v.v_.generic_name()) << ",\n" + << v.line_prefix_ << "\t" << v.v_.bit_position() << ",\n" + << v.line_prefix_ << "\t" << v.v_.bit_size() << ",\n" + << v.line_prefix_ << "\t" << gen(v.v_.factor()) << ", \n" + << v.line_prefix_ << "\t" << v.v_.offset() << ", \n" + << v.line_prefix_ << "\t" << "0,\n" + << v.line_prefix_ << "\t" << "0,\n" + << v.line_prefix_ << "\tfrequency_clock_t(" << gen(v.v_.max_frequency()) << "),\n" + << v.line_prefix_ << "\t" << gen(v.v_.send_same()) << ",\n" + << v.line_prefix_ << "\t" << gen(v.v_.force_send_changed()) << ",\n" + << gen(v.v_.states(), v.line_prefix_ + '\t') << ",\n" + << v.line_prefix_ << '\t' << gen(v.v_.writable()) << ",\n" + << v.line_prefix_ << '\t' << (v.v_.decoder().size() ? v.v_.decoder() : "nullptr") << ",\n" + << v.line_prefix_ << '\t' << (v.v_.encoder().size() ? v.v_.encoder() : "nullptr") << ",\n" + << v.line_prefix_ << '\t' << "false\n" + << v.line_prefix_ << "}"; + return o; +} + +template <> +std::ostream& operator<<(std::ostream& o, const generator& v) +{ + o << v.line_prefix_ << "{\n" + << v.line_prefix_ << "\t" << v.v_.pid() << ",\n" + << v.line_prefix_ << "\t" << gen(v.v_.name()) << ",\n" + << v.line_prefix_ << "\t" << 0 << ",\n" + << 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" << (v.v_.callback().size() ? v.v_.callback() : "nullptr") << ",\n" + << v.line_prefix_ << "\t" << "true" << "\n" + << v.line_prefix_ << "}"; + return o; +} + +/// @brief Generate the configuration code. +/// @param[in] header Content to be inserted as a header. +/// @param[in] footer Content to be inserted as a footer. +/// @param[in] message_set Configuration read from the json file. +/// @param[in] out Stream to write on. +void generate(const std::string& header, const std::string& footer, const openxc::message_set& message_set, std::ostream& out) +{ + out << "#include \"configuration.hpp\"\n" + << "#include \"can/can-decoder.hpp\"\n\n"; + + if (header.size()) out << header << "\n"; + + out << "configuration_t::configuration_t()\n" + << " : can_message_set_{" << gen(message_set) << "}\n" + << " , can_message_definition_\n" + << " {\n" + << gen(message_set.messages(), "\t\t") << '\n' + << " }\n" + << " , can_signals_\n" + << " {\n"; + std::uint32_t message_count = message_set.messages().size(); + std::uint32_t index = 0; + for(const openxc::can_message& m : message_set.messages()) + { + out << " {\n"; + std::uint32_t signal_count = m.signals().size(); + for(const openxc::signal& s : m.signals()) + { + out << gen(s, index, " "); + if (signal_count > 1) out << ','; + --signal_count; + out << '\n'; + } + out << " }"; + if (index + 1 < message_count) out << ','; + ++index; + out << '\n'; + } + out << " }\n" + << " , diagnostic_messages_\n" + << " {\n" + << gen(message_set.diagnostic_messages(), " ") << "\n" + << " }\n" + << "{\n" + << "}\n\n" + << "const std::string configuration_t::get_diagnostic_bus() const\n" + << "{\n"; + + std::string active_bus = ""; + for (const auto& d : message_set.diagnostic_messages()) + { + if (d.bus().size() == 0) std::cerr << "ERROR: The bus name should be set for each diagnostic message." << std::endl; + if (active_bus.size() == 0) active_bus = d.bus(); + if (active_bus != d.bus()) std::cerr << "ERROR: The bus name should be the same for each diagnostic message." << std::endl; + } + + out << " return " << gen(active_bus) << ";\n" + << "}\n\n"; + out << footer << std::endl; +} + +/// @brief Read whole file content to a string. +/// @param[in] file Path to the file. +/// @return A std::string which contains the file content. If @c file is an empty string, the return value is also empty. +/// @exception std::runtime_error Throw this exception if the specified file is not found or cannot be opened. +std::string read_file(const std::string& file) +{ + if(file.size() == 0) return std::string(); + + std::string content; + std::ifstream stream(file); + if (stream) + { + stream.seekg(0, std::ios::end); + content.reserve(stream.tellg()); + stream.seekg(0, std::ios::beg); + content.assign((std::istreambuf_iterator(stream)), std::istreambuf_iterator()); + return content; + } + std::stringstream ss; + ss << "The specified file (" << file << ") is not found!"; + throw std::runtime_error(ss.str()); +} + +/// @brief Read whole file content as a json document. +/// @param[in] file Path to the file. +/// @return A @c nlohmann::json object. +/// @exception std::runtime_error Throw this exception if the specified file is not found or cannot be opened. +nlohmann::json read_json(const std::string& file) +{ + std::ifstream stream(file); + if (stream) + { + nlohmann::json result; + stream >> result; + return result; + } + std::stringstream ss; + ss << "The specified file (" << file << ") is not found!"; + throw std::runtime_error(ss.str()); +} + +// function that show the help information +void showhelpinfo(char *s) +{ +std::cout<<"Usage: "< [-o configuration-generated.cpp]"<< std::endl; +std::cout<<"option: "<<"-m input.json : JSON file describing CAN messages and signals"<< std::endl; +std::cout<<" "<<"-h header.cpp : header source file insert at the beginning of generated file"<< std::endl; +std::cout<<" "<<"-f footer.cpp : footer source file append to generated file."<< std::endl; +std::cout<<" "<<"-o configuration-generated.cpp : output source file. Name has to be configuration-generated.cpp"<< std::endl; +} + +/// @brief Entry point. +/// @param[in] argc Argument's count. +/// @param[in] argv Argument's array. +/// @return Exit code, zero if success. +int main(int argc, char *argv[]) +{ + try + { + std::string appName = argv[0]; + std::string message_set_file; + std::string output_file; + std::string header_file; + std::string footer_file; + + char tmp; + /*if the program is ran witout options ,it will show the usgage and exit*/ + if(argc == 1) + { + showhelpinfo(argv[0]); + exit(1); + } + /*use function getopt to get the arguments with option."hu:p:s:v" indicate + that option h,v are the options without arguments while u,p,s are the + options with arguments*/ + while((tmp=getopt(argc,argv,"m:h:f:o:"))!=-1) + { + switch(tmp) + { + case 'h': + header_file = optarg; + break; + case 'f': + footer_file = optarg; + break; + case 'm': + message_set_file = optarg; + break; + case 'o': + output_file = optarg; + break; + default: + showhelpinfo(argv[0]); + break; + } + } + + std::stringstream header; + header << read_file(header_file); + + std::string footer = read_file(footer_file); + openxc::message_set message_set; + message_set.from_json(read_json(message_set_file)); + + std::string message_set_path = dirname(strdup(message_set_file.c_str())); + for(const auto& s : message_set.extra_sources()) + { + std::string extra_source = s; + extra_source = message_set_path + "/" + extra_source; + header << "\n// >>>>> " << s << " >>>>>\n" << read_file(extra_source) << "\n// <<<<< " << s << " <<<<<\n"; + } + + std::ofstream out; + if (output_file.size()) + { + out.open(output_file); + if(!out) + { + std::stringstream ss; + ss << "Can't open the ouput file (" << output_file << ") for writing!"; + throw std::runtime_error(ss.str()); + } + } + generate(header.str(), footer, message_set, output_file.size() ? out : std::cout); + } + catch (std::exception& e) + { + std::cerr << "ERROR: Unhandled exception - " << e.what() << std::endl; + return EXIT_UNKNOWN_ERROR; + } + return EXIT_SUCCESS; +} diff --git a/CAN-config-generator/src/main.hpp b/CAN-config-generator/src/main.hpp new file mode 100644 index 00000000..cf08e1a4 --- /dev/null +++ b/CAN-config-generator/src/main.hpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015, 20"IoT.bzh" + * Author "Romain Forlot" + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +struct afb_config_list { + struct afb_config_list *next; + char *value; +}; + +// main config structure +struct afb_config { + char *console; // console device name (can be a file or a tty) + char *rootdir; // base dir for files + char *roothttp; // directory for http files + char *rootbase; // Angular HTML5 base URL + char *rootapi; // Base URL for REST APIs + char *workdir; // where to run the program + char *uploaddir; // where to store transient files + char *token; // initial authentication token [default NULL no session] + + struct afb_config_list *aliases; + struct afb_config_list *dbus_clients; + struct afb_config_list *dbus_servers; + struct afb_config_list *ws_clients; + struct afb_config_list *ws_servers; + struct afb_config_list *so_bindings; + struct afb_config_list *ldpaths; + + char **exec; + + int httpdPort; + int background; // run in backround mode + int cacheTimeout; + int apiTimeout; + int cntxTimeout; // Client Session Context timeout + int nbSessionMax; // max count of sessions + int mode; // mode of listening + int tracereq; + int noHttpd; +}; + +extern struct afb_config *parse_arguments(int argc, char **argv); \ No newline at end of file diff --git a/CAN-config-generator/src/openxc/can_bus.cpp b/CAN-config-generator/src/openxc/can_bus.cpp new file mode 100755 index 00000000..0a968a9e --- /dev/null +++ b/CAN-config-generator/src/openxc/can_bus.cpp @@ -0,0 +1,89 @@ +#include "can_bus.hpp" + +namespace openxc +{ + std::uint32_t can_bus::controller() const + { + return controller_; + } + + std::uint32_t can_bus::speed() const + { + return speed_; + } + + can_bus_mode can_bus::raw_can_mode() const + { + return raw_can_mode_; + } + + bool can_bus::raw_writable() const + { + return raw_writable_; + } + + float can_bus::max_message_frequency() const + { + return max_message_frequency_; + } + + bool can_bus::force_send_changed() const + { + return force_send_changed_; + } + + void can_bus::from_json(const nlohmann::json& j) + { + controller_ = j.count("controller") ? j["controller"].get() : 1; + speed_ = j.count("speed") ? j["speed"].get() : 0; + raw_can_mode_ = j.count("raw_can_mode") ? j["raw_can_mode"].get() : can_bus_mode::off; + raw_writable_ = j.count("raw_writable") ? j["raw_writable"].get() : false; + max_message_frequency_ = j.count("max_message_frequency") ? j["max_message_frequency"].get() : 0; + force_send_changed_ = j.count("force_send_changed") ? j["force_send_changed"].get() : false; + } + + nlohmann::json can_bus::to_json() const + { + nlohmann::json j; + j["controller"] = controller_; + j["speed"] = speed_; + j["raw_can_mode"] = raw_can_mode_; + j["raw_writable"] = raw_writable_; + j["max_message_frequency"] = max_message_frequency_; + j["force_send_changed"] = force_send_changed_; + return j; + } + + void to_json(nlohmann::json& j, const can_bus& p) + { + j = p.to_json(); + } + + void from_json(const nlohmann::json& j, can_bus& p) + { + p.from_json(j); + } + + void to_json(nlohmann::json& j, const can_bus_mode& p) + { + switch (p) + { + case can_bus_mode::off: + j = std::string("off"); + break; + case can_bus_mode::filtered: + j = std::string("filtered"); + break; + case can_bus_mode::unfiltered: + j = std::string("unfiltered"); + break; + } + } + + void from_json(const nlohmann::json& j, can_bus_mode& p) + { + if (j.get() == "off") p = can_bus_mode::off; + else if (j.get() == "filtered") p = can_bus_mode::filtered; + else p = can_bus_mode::unfiltered; + } +} diff --git a/CAN-config-generator/src/openxc/can_bus.hpp b/CAN-config-generator/src/openxc/can_bus.hpp new file mode 100755 index 00000000..74e1273f --- /dev/null +++ b/CAN-config-generator/src/openxc/can_bus.hpp @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +namespace openxc +{ + enum class can_bus_mode + { + off, + filtered, + unfiltered + }; + + class can_bus + { + private: + std::uint32_t controller_; + std::uint32_t speed_; + can_bus_mode raw_can_mode_; + bool raw_writable_; + float max_message_frequency_; + bool force_send_changed_; + + public: + std::uint32_t controller() const; + std::uint32_t speed() const; + can_bus_mode raw_can_mode() const; + bool raw_writable() const; + float max_message_frequency() const; + bool force_send_changed() const; + + void from_json(const nlohmann::json& j); + nlohmann::json to_json() const; + }; + + void to_json(nlohmann::json& j, const can_bus& p); + void from_json(const nlohmann::json& j, can_bus& p); + + void to_json(nlohmann::json& j, const can_bus_mode& p); + void from_json(const nlohmann::json& j, can_bus_mode& p); +} diff --git a/CAN-config-generator/src/openxc/can_message.cpp b/CAN-config-generator/src/openxc/can_message.cpp new file mode 100755 index 00000000..fab5a85f --- /dev/null +++ b/CAN-config-generator/src/openxc/can_message.cpp @@ -0,0 +1,126 @@ +#include "can_message.hpp" + +namespace openxc +{ + std::string can_message::id() const + { + return id_; + } + + void can_message::id(const std::string& id) + { + id_ = id; + } + + std::string can_message::bus() const + { + return bus_; + } + + bool can_message::bit_numbering_inverted() const + { + return bit_numbering_inverted_; + } + + const std::vector& can_message::signals() const + { + return signals_; + } + + std::string can_message::name() const + { + return name_; + } + + std::vector can_message::handlers() const + { + return handlers_; + } + + bool can_message::enabled() const + { + return enabled_; + } + + float can_message::max_frequency() const + { + return max_frequency_; + } + + float can_message::max_signal_frequency() const + { + return max_signal_frequency_; + } + + bool can_message::force_send_changed() const + { + return force_send_changed_; + } + + bool can_message::force_send_changed_signals() const + { + return force_send_changed_; + } + + void can_message::from_json(const nlohmann::json& j) + { + bus_ = j.count("bus") ? j["bus"].get() : ""; + bit_numbering_inverted_ = j.count("bit_numbering_inverted") ? j["bit_numbering_inverted"].get() : false; + name_ = j.count("name") ? j["name"].get() : ""; + handlers_ = j.count("handlers") ? j["handlers"].get>() : std::vector(); + enabled_ = j.count("enabled") ? j["enabled"].get() : true; + max_frequency_ = j.count("max_frequency") ? j["max_frequency"].get() : 0; + max_signal_frequency_ = j.count("max_signal_frequency") ? j["max_signal_frequency"].get() : 0; + force_send_changed_ = j.count("force_send_changed") ? j["force_send_changed"].get() : true; + force_send_changed_signals_ = j.count("force_send_changed_signals") ? j["force_send_changed_signals"].get() : false; + + if(j.count("signals")) + { + std::map signals = j["signals"]; + for(const auto& s : signals) + { + signal sig = s.second.get(); + sig.id(s.first); + signals_.push_back(sig); + } + } + + } + + std::uint32_t can_message::get_signals_count() const + { + return signals_.size(); + } + + nlohmann::json can_message::to_json() const + { + nlohmann::json j; + j["bus"] = bus_; + j["bit_numbering_inverted"] = bit_numbering_inverted_; + j["signals"] = signals_; + j["name"] = name_; + j["handlers"] = handlers_; + j["enabled"] = enabled_; + j["max_frequency"] = max_frequency_; + j["max_signal_frequency"] = max_signal_frequency_; + j["force_send_changed"] = force_send_changed_; + j["force_send_changed_signals"] = force_send_changed_signals_; + return j; + } + + void to_json(nlohmann::json& j, const can_message& p) + { + j = p.to_json(); + } + + void from_json(const nlohmann::json& j, can_message& p) + { + p.from_json(j); + } + + void from_json(const nlohmann::json& j, can_message& p, const std::string& id) + { + p.from_json(j); + p.id(id); + } +} diff --git a/CAN-config-generator/src/openxc/can_message.hpp b/CAN-config-generator/src/openxc/can_message.hpp new file mode 100755 index 00000000..3f7b0181 --- /dev/null +++ b/CAN-config-generator/src/openxc/can_message.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include + +#include "signal.hpp" + +namespace openxc +{ + class can_message + { + private: + std::string id_; + std::string bus_; + bool bit_numbering_inverted_; + std::vector signals_; + std::string name_; + std::vector handlers_; + bool enabled_; + float max_frequency_; + float max_signal_frequency_; + bool force_send_changed_; + bool force_send_changed_signals_; + + public: + std::string id() const; + void id(const std::string& id); + std::string bus() const; + bool bit_numbering_inverted() const; + const std::vector& signals() const; + std::string name() const; + std::vector handlers() const; + bool enabled() const; + float max_frequency() const; + float max_signal_frequency() const; + bool force_send_changed() const; + bool force_send_changed_signals() const; + + void from_json(const nlohmann::json& j); + nlohmann::json to_json() const; + + std::uint32_t get_signals_count() const; + }; + + void to_json(nlohmann::json& j, const can_message& p); + void from_json(const nlohmann::json& j, can_message& p); + void from_json(const nlohmann::json& j, can_message& p, const std::string& id); +} diff --git a/CAN-config-generator/src/openxc/command.cpp b/CAN-config-generator/src/openxc/command.cpp new file mode 100755 index 00000000..4cc0682f --- /dev/null +++ b/CAN-config-generator/src/openxc/command.cpp @@ -0,0 +1,45 @@ +#include "command.hpp" + +namespace openxc +{ + std::string command::name() const + { + return name_; + } + + bool command::enabled() const + { + return enabled_; + } + + std::string command::handler() const + { + return handler_; + } + + void command::from_json(const nlohmann::json& j) + { + name_ = j.count("name") ? j["name"].get() : ""; + enabled_ = j.count("enabled") ? j["enabled"].get() : true; + handler_ = j.count("handler") ? j["handler"].get() : ""; + } + + nlohmann::json command::to_json() const + { + nlohmann::json j; + j["name"] = name_; + j["enabled"] = enabled_; + j["handler"] = handler_; + return j; + } + + void to_json(nlohmann::json& j, const command& p) + { + j = p.to_json(); + } + + void from_json(const nlohmann::json& j, command& p) + { + p.from_json(j); + } +} diff --git a/CAN-config-generator/src/openxc/command.hpp b/CAN-config-generator/src/openxc/command.hpp new file mode 100755 index 00000000..2c052266 --- /dev/null +++ b/CAN-config-generator/src/openxc/command.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +namespace openxc +{ + class command + { + private: + std::string name_; + bool enabled_; + std::string handler_; + public: + std::string name() const; + bool enabled() const; + std::string handler() const; + + void from_json(const nlohmann::json& j); + nlohmann::json to_json() const; + }; + + void to_json(nlohmann::json& j, const command& p); + void from_json(const nlohmann::json& j, command& p); +} diff --git a/CAN-config-generator/src/openxc/diagnostic_message.cpp b/CAN-config-generator/src/openxc/diagnostic_message.cpp new file mode 100755 index 00000000..3881abef --- /dev/null +++ b/CAN-config-generator/src/openxc/diagnostic_message.cpp @@ -0,0 +1,80 @@ +#include "diagnostic_message.hpp" + +namespace openxc +{ + std::string diagnostic_message::bus() const + { + return bus_; + } + + std::uint32_t diagnostic_message::id() const + { + return id_; + } + + std::uint32_t diagnostic_message::mode() const + { + return mode_; + } + + float diagnostic_message::frequency() const + { + return frequency_; + } + + std::uint32_t diagnostic_message::pid() const + { + return pid_; + } + + std::string diagnostic_message::name() const + { + return name_; + } + + std::string diagnostic_message::decoder() const + { + return decoder_; + } + + std::string diagnostic_message::callback() const + { + return callback_; + } + + void diagnostic_message::from_json(const nlohmann::json& j) + { + bus_ = j.count("bus") ? j["bus"].get() : ""; + id_ = j.count("id") ? j["id"].get() : 0; + mode_ = j.count("mode") ? j["mode"].get() : 1; + frequency_ = j.count("frequency") ? j["frequency"].get() : 0; + pid_ = j.count("pid") ? j["pid"].get() : 0; + name_ = j.count("name") ? j["name"].get() : ""; + decoder_ = j.count("decoder") ? j["decoder"].get() : ""; + callback_ = j.count("callback") ? j["callback"].get() : ""; + } + + nlohmann::json diagnostic_message::to_json() const + { + nlohmann::json j; + j["bus"] = bus_; + j["id"] = id_; + j["mode"] = mode_; + j["frequency"] = frequency_; + j["pid"] = pid_; + j["name"] = name_; + j["decoder"] = decoder_; + j["callback"] = callback_; + return j; + } + + void to_json(nlohmann::json& j, const diagnostic_message& p) + { + j = p.to_json(); + } + + void from_json(const nlohmann::json& j, diagnostic_message& p) + { + p.from_json(j); + } +} diff --git a/CAN-config-generator/src/openxc/diagnostic_message.hpp b/CAN-config-generator/src/openxc/diagnostic_message.hpp new file mode 100755 index 00000000..1ceba1bd --- /dev/null +++ b/CAN-config-generator/src/openxc/diagnostic_message.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +namespace openxc +{ + class diagnostic_message + { + private: + std::string bus_; + std::uint32_t id_; + std::uint32_t mode_; + float frequency_; + std::uint32_t pid_; + std::string name_; + std::string decoder_; + std::string callback_; + public: + std::string bus() const; + std::uint32_t id() const; + std::uint32_t mode() const; + float frequency() const; + std::uint32_t pid() const; + std::string name() const; + std::string decoder() const; + std::string callback() const; + + void from_json(const nlohmann::json& j); + nlohmann::json to_json() const; + }; + + void to_json(nlohmann::json& j, const diagnostic_message& p); + void from_json(const nlohmann::json& j, diagnostic_message& p); +} diff --git a/CAN-config-generator/src/openxc/mapping.cpp b/CAN-config-generator/src/openxc/mapping.cpp new file mode 100755 index 00000000..74d5c94e --- /dev/null +++ b/CAN-config-generator/src/openxc/mapping.cpp @@ -0,0 +1,59 @@ +#include "mapping.hpp" + +namespace openxc +{ + std::string mapping::mapping_name() const + { + return mapping_name_; + } + + std::string mapping::bus() const + { + return bus_; + } + + std::string mapping::database() const + { + return database_; + } + + bool mapping::bit_numbering_inverted() const + { + return bit_numbering_inverted_; + } + + bool mapping::enabled() const + { + return enabled_; + } + + void mapping::from_json(const nlohmann::json& j) + { + mapping_name_ = j.count("mapping") ? j["mapping"].get() : ""; + bus_ = j.count("bus") ? j["bus"].get() : ""; + database_ = j.count("database") ? j["database"].get() : ""; + bit_numbering_inverted_ = j.count("bit_numbering_inverted") ? j["bit_numbering_inverted"].get() : false; + enabled_ = j.count("enabled") ? j["enabled"].get() : true; + } + + nlohmann::json mapping::to_json() const + { + nlohmann::json j; + j["mapping"] = mapping_name_; + j["bus"] = bus_; + j["database"] = database_; + j["bit_numbering_inverted"] = bit_numbering_inverted_; + j["enabled"] = enabled_; + return j; + } + + void to_json(nlohmann::json& j, const mapping& p) + { + j = p.to_json(); + } + + void from_json(const nlohmann::json& j, mapping& p) + { + p.from_json(j); + } +} diff --git a/CAN-config-generator/src/openxc/mapping.hpp b/CAN-config-generator/src/openxc/mapping.hpp new file mode 100755 index 00000000..30895cba --- /dev/null +++ b/CAN-config-generator/src/openxc/mapping.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +namespace openxc +{ + class mapping + { + private: + std::string mapping_name_; + std::string bus_; + std::string database_; + bool bit_numbering_inverted_; + bool enabled_; + public: + std::string mapping_name() const; + std::string bus() const; + std::string database() const; + bool bit_numbering_inverted() const; + bool enabled() const; + + void from_json(const nlohmann::json& j); + nlohmann::json to_json() const; + }; + + void to_json(nlohmann::json& j, const mapping& p); + void from_json(const nlohmann::json& j, mapping& p); +} diff --git a/CAN-config-generator/src/openxc/message_set.cpp b/CAN-config-generator/src/openxc/message_set.cpp new file mode 100755 index 00000000..c47c45f8 --- /dev/null +++ b/CAN-config-generator/src/openxc/message_set.cpp @@ -0,0 +1,145 @@ +#include +#include "message_set.hpp" + +namespace openxc +{ + message_set::message_set() + : name_{""} + , bit_numbering_inverted_{false} + , max_message_frequency_{0} + , raw_can_mode_{can_bus_mode::off} + , parents_{} + , initializers_{} + , loopers_{} + , buses_{} + , messages_{} + , diagnostic_messages_{} + , mappings_{} + , extra_sources_{} + , commands_{} + { + } + + std::string message_set::name() const + { + return name_; + } + + 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& message_set::parents() const + { + return parents_; + } + + const std::vector& message_set::initializers() const + { + return initializers_; + } + + const std::vector& message_set::loopers() const + { + return loopers_; + } + + const std::map& message_set::buses() const + { + return buses_; + } + + const std::vector& message_set::messages() const + { + return messages_; + } + + const std::vector& message_set::diagnostic_messages() const + { + return diagnostic_messages_; + } + + const std::vector& message_set::mappings() const + { + return mappings_; + } + + const std::vector& message_set::extra_sources() const + { + return extra_sources_; + } + + const std::vector& message_set::commands() const + { + return commands_; + } + + void message_set::from_json(const nlohmann::json& j) + { + name_ = j["name"].get(); + bit_numbering_inverted_ = j.count("bit_numbering_inverted") ? j["bit_numbering_inverted"].get() : false; // TODO: should be true by default if database-backed. + max_message_frequency_ = j.count("max_message_frequency") ? j["max_message_frequency"].get() : 0; + raw_can_mode_ = j.count("raw_can_mode") ? j["raw_can_mode"].get() : can_bus_mode::off; + parents_ = j.count("parents") ? j["parents"].get>() : std::vector(); + initializers_ = j.count("initializers") ? j["initializers"].get>() : std::vector(); + loopers_ = j.count("loopers") ? j["loopers"].get>() : std::vector(); + buses_ = j.count("buses") ? j["buses"].get>() : std::map(); + //messages_ = j.count("messages") ? j["messages"].get>() : std::map(); + diagnostic_messages_ = j.count("diagnostic_messages") ? j["diagnostic_messages"].get>() : std::vector(); + mappings_ = j.count("mappings") ? j["mappings"].get>() : std::vector(); + extra_sources_ = j.count("extra_sources") ? j["extra_sources"].get>() : std::vector(); + commands_ = j.count("commands") ? j["commands"].get>() : std::vector(); + + + if (j.count("messages")) + { + std::map messages = j["messages"]; + for(const std::map::value_type& m : messages) + { + can_message cm = m.second.get(); + cm.id(m.first); + messages_.push_back(cm); + } + } + } + + nlohmann::json message_set::to_json() const + { + nlohmann::json j; + j["name_"] = name_; + j["bit_numbering_inverted"] = bit_numbering_inverted_; + j["max_message_frequency"] = max_message_frequency_; + j["raw_can_mode"] = raw_can_mode_; + j["parents"] = parents_; + j["initializers"] = initializers_; + j["loopers"] = loopers_; + j["buses"] = buses_; + j["messages"] = messages_; + j["diagnostic_messages"] = diagnostic_messages_; + j["mappings"] = mappings_; + j["extra_sources"] = extra_sources_; + j["commands"] = commands_; + return j; + } + + void to_json(nlohmann::json& j, const message_set& p) + { + j = p.to_json(); + } + + void from_json(const nlohmann::json& j, message_set& p) + { + p.from_json(j); + } +} diff --git a/CAN-config-generator/src/openxc/message_set.hpp b/CAN-config-generator/src/openxc/message_set.hpp new file mode 100755 index 00000000..935817ee --- /dev/null +++ b/CAN-config-generator/src/openxc/message_set.hpp @@ -0,0 +1,59 @@ +#pragma once + +#include +#include +#include +#include + +#include "can_bus.hpp" +#include "can_message.hpp" +#include "diagnostic_message.hpp" +#include "mapping.hpp" +#include "command.hpp" + +namespace openxc +{ + class message_set + { + private: + std::string name_; + bool bit_numbering_inverted_; + float max_message_frequency_; + can_bus_mode raw_can_mode_; + std::vector parents_; + std::vector initializers_; + std::vector loopers_; + std::map buses_; + //std::map messages_; + std::vector messages_; + std::vector diagnostic_messages_; + std::vector mappings_; + std::vector extra_sources_; + std::vector commands_; + + public: + message_set(); + message_set(const message_set&) = default; + message_set(message_set&&) = default; + + std::string name() const; + bool bit_numbering_inverted() const; + float max_message_frequency() const; + can_bus_mode raw_can_mode() const; + const std::vector& parents() const; + const std::vector& initializers() const; + const std::vector& loopers() const; + const std::map& buses() const; + const std::vector& messages() const; + const std::vector& diagnostic_messages() const; + const std::vector& mappings() const; + const std::vector& extra_sources() const; + const std::vector& commands() const; + + void from_json(const nlohmann::json& j); + nlohmann::json to_json() const; + }; + + void to_json(nlohmann::json& j, const message_set& p); + void from_json(const nlohmann::json& j, message_set& p); +} diff --git a/CAN-config-generator/src/openxc/signal.cpp b/CAN-config-generator/src/openxc/signal.cpp new file mode 100755 index 00000000..6c3ff82a --- /dev/null +++ b/CAN-config-generator/src/openxc/signal.cpp @@ -0,0 +1,142 @@ +#include "signal.hpp" + +namespace openxc +{ + std::string signal::id() const + { + return id_; + } + + void signal::id(const std::string& id) + { + id_ = id; + } + + void id(const std::string& id); + + std::string signal::generic_name() const + { + return generic_name_; + } + + std::uint32_t signal::bit_position() const + { + return bit_position_; + } + + std::uint32_t signal::bit_size() const + { + return bit_size_; + } + + float signal::factor() const + { + return factor_; + } + + std::uint32_t signal::offset() const + { + return offset_; + } + + std::string signal::decoder() const + { + return decoder_; + } + + bool signal::ignore() const + { + return ignore_; + } + + bool signal::enabled() const + { + return enabled_; + } + + const std::map>& signal::states() const + { + return states_; + } + + float signal::max_frequency() const + { + return max_frequency_; + } + + bool signal::send_same() const + { + return send_same_; + } + + bool signal::force_send_changed() const + { + return force_send_changed_; + } + + bool signal::writable() const + { + return writable_; + } + + std::string signal::encoder() const + { + return encoder_; + } + + void signal::from_json(const nlohmann::json& j) + { + generic_name_ = j.count("generic_name") ? j["generic_name"].get() : ""; + bit_position_ = j.count("bit_position") ? j["bit_position"].get() : 0; + bit_size_ = j.count("bit_size") ? j["bit_size"].get() : 0; + factor_ = j.count("factor") ? j["factor"].get() : 1.0f; + offset_ = j.count("offset") ? j["offset"].get() : 0; + decoder_ = j.count("decoder") ? j["decoder"].get() : ""; + ignore_ = j.count("ignore") ? j["ignore"].get() : false; + enabled_ = j.count("enabled") ? j["enabled"].get() : true; + max_frequency_ = j.count("max_frequency") ? j["max_frequency"].get() : 0; + send_same_ = j.count("send_same") ? j["send_same"].get() : true; + force_send_changed_ = j.count("force_send_changed") ? j["force_send_changed"].get() : false; + writable_ = j.count("writable") ? j["writable"].get() : false; + encoder_ = j.count("encoder") ? j["encoder"].get() : ""; + + if (j.count("states")) + { + std::map items = j["states"]; + for(const auto& i : items) + { + states_[i.first] = i.second.get>(); + } + } + } + + nlohmann::json signal::to_json() const + { + nlohmann::json j; + j["generic_name"] = generic_name_; + j["bit_position"] = bit_position_; + j["bit_size"] = bit_size_; + j["factor"] = factor_; + j["offset"] = offset_; + j["decoder"] = decoder_; + j["ignore"] = ignore_; + j["enabled"] = enabled_; + j["states"] = states_; + j["max_frequency"] = max_frequency_; + j["send_same"] = send_same_; + j["force_send_changed"] = force_send_changed_; + j["writable"] = writable_; + j["encoder"] = encoder_; + return j; + } + + void to_json(nlohmann::json& j, const signal& p) + { + j = p.to_json(); + } + + void from_json(const nlohmann::json& j, signal& p) + { + p.from_json(j); + } +} diff --git a/CAN-config-generator/src/openxc/signal.hpp b/CAN-config-generator/src/openxc/signal.hpp new file mode 100755 index 00000000..64dba75e --- /dev/null +++ b/CAN-config-generator/src/openxc/signal.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace openxc +{ + class signal + { + private: + std::string id_; + std::string generic_name_; + std::uint32_t bit_position_; + std::uint32_t bit_size_; + float factor_; + std::uint32_t offset_; + std::string decoder_; + bool ignore_; + bool enabled_; + std::map> states_; + float max_frequency_; + bool send_same_; + bool force_send_changed_; + bool writable_; + std::string encoder_; + public: + std::string id() const; + void id(const std::string& id); + std::string generic_name() const; + std::uint32_t bit_position() const; + std::uint32_t bit_size() const; + float factor() const; + std::uint32_t offset() const; + std::string decoder() const; + bool ignore() const; + bool enabled() const; + const std::map>& states() const; + float max_frequency() const; + bool send_same() const; + bool force_send_changed() const; + bool writable() const; + std::string encoder() const; + + void from_json(const nlohmann::json& j); + nlohmann::json to_json() const; + }; + + void to_json(nlohmann::json& j, const signal& p); + void from_json(const nlohmann::json& j, signal& p); +} -- cgit 1.2.3-korg