aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--src/main.cpp152
-rw-r--r--src/main.hpp55
-rwxr-xr-xsrc/openxc/signal.cpp23
-rwxr-xr-xsrc/openxc/signal.hpp25
5 files changed, 97 insertions, 160 deletions
diff --git a/Makefile b/Makefile
index 658ef32..35eed16 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,7 @@ BUILD_DIR := build
.PHONY: all clean mrproper ${BUILD_DIR}/Makefile
-all: build package
+all: build
clean:
@([ -d ${BUILD_DIR} ] && make -C ${BUILD_DIR} clean) || echo Nothing to clean
diff --git a/src/main.cpp b/src/main.cpp
index c001df3..660c347 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -35,18 +35,40 @@
#define EXIT_PROGRAM_ERROR 3
-/**
+/*
* FLAGS
+ *
+ * Taken from include/low-can/can-message.hpp in agl-service-can-low-level.
+ * The flags values in the generated message_definition_t definitions needs to
+ * match usage of these flags in the binding, e.g. in the various member
+ * functions in low-can-binding/can/message-definition.cpp.
+ *
+ * ATM the only flags known to be used are:
+ *
+ * CAN_PROTOCOL_WITH_FD_FRAME
+ * J1939_PROTOCOL
+ * ISOTP_PROTOCOL
+ * BYTE_FRAME_IS_BIG_ENDIAN
+ *
+ * Note that for BYTE_FRAME_IS_BIG_ENDIAN, even though it is referenced in
+ * message-definition.cpp, the member function that does so seems currently
+ * unused, so it is not clear what the intended usage actually is.
+ * The JSON parser for CAN messages would likely need an additional field
+ * added to allow setting it, for now that is being left for a future update.
*/
-#define INVALID_FLAG 0x0001
-#define STANDARD_ID 0x0002
-#define EXTENDED_ID 0x0004
-#define BCM_PROTOCOL 0x0008
-#define J1939_PROTOCOL 0x0010
-#define J1939_ADDR_CLAIM_PROTOCOL 0x0020
-#define ISOTP_PROTOCOL 0x0040
-#define FD_FRAME 0x0800
+#define CAN_PROTOCOL 0x0001
+#define CAN_PROTOCOL_WITH_FD_FRAME 0x0002
+#define J1939_ADDR_CLAIM_PROTOCOL 0x0004
+#define J1939_PROTOCOL 0x0008
+#define ISOTP_PROTOCOL 0x0010
+#define ISOTP_SEND 0x0020
+#define ISOTP_RECEIVE 0x0040
+#define BYTE_FRAME_IS_BIG_ENDIAN 0x0080
+#define BIT_POSITION_REVERSED 0x0100
+#define CONTINENTAL_BIT_POSITION 0x0200
+#define INVALID_FLAG 0x8000
+
#define VERSION_LOW_CAN "2.0"
@@ -128,17 +150,17 @@ std::ostream& operator<<(std::ostream& o, const generator<std::vector<T>>& v)
template <>
std::ostream& operator<<(std::ostream& o, const generator<openxc::message_set>& v)
{
- o << v.line_prefix_
- << "{std::make_shared<message_set_t>(message_set_t{"
+ o << "std::shared_ptr<message_set_t> cms = "
+ << "std::make_shared<message_set_t>(message_set_t{"
<< "0,"
<< gen(v.v_.name()) << ",\n"
- << "\t\t\t{ // beginning message_definition_ vector\n"
- << gen(v.v_.messages(), "\t\t\t")
- << "\n\t\t}, // end message_definition vector\n"
- << "\t\t\t{ // beginning diagnostic_messages_ vector\n"
- << gen(v.v_.diagnostic_messages(),"\t\t\t") << "\n"
- << "\t\t\t} // end diagnostic_messages_ vector\n"
- << "\t\t})} // end message_set entry\n";
+ << "\t{ // beginning message_definition_ vector\n"
+ << gen(v.v_.messages(), "\t")
+ << "\t}, // end message_definition vector\n"
+ << "\t{ // beginning diagnostic_messages_ vector\n"
+ << gen(v.v_.diagnostic_messages(),"\t") << "\n"
+ << "\t} // end diagnostic_messages_ vector\n"
+ << "}); // end message_set entry\n";
return o;
}
@@ -192,8 +214,8 @@ std::ostream& operator<<(std::ostream& o, const generator<openxc::signal>& v)
}
std::string multi = "std::make_pair<bool, int>(" + multi_first + ", " + std::to_string(v.v_.multiplex().second) + ")";
o << v.line_prefix_ << '\t' << multi << ",// multiplex\n"
- << v.line_prefix_ << '\t' << gen(v.v_.is_big_endian()) << ",// is_big_endian\n"
- << v.line_prefix_ << '\t' << gen(v.v_.is_signed()) << ",// is_signed\n"
+ << v.line_prefix_ << "\tstatic_cast<sign_t>(" << gen(v.v_.sign()) << "),// signed\n"
+ << v.line_prefix_ << '\t' << gen(v.v_.bit_sign_position()) << ",// bit_sign_position\n"
<< v.line_prefix_ << "\t" << gen(v.v_.unit()) << "// unit\n"
<< v.line_prefix_ << "})}";
return o;
@@ -207,11 +229,11 @@ std::ostream& operator<<(std::ostream& o, const generator<openxc::can_message>&
<< gen(v.v_.bus()) << ","
<< v.v_.id() << ","
<< "\"" << v.v_.name() << "\","
- << v.v_.length() << ",";
+ << (v.v_.length() != 0 ? v.v_.length() : 8) << ",";
uint32_t flags = 0;
if(v.v_.is_fd())
{
- flags = flags|FD_FRAME;
+ flags = flags|CAN_PROTOCOL_WITH_FD_FRAME;
}
if(v.v_.is_j1939())
@@ -224,37 +246,22 @@ std::ostream& operator<<(std::ostream& o, const generator<openxc::can_message>&
flags = flags|ISOTP_PROTOCOL;
}
- if(v.v_.is_extended())
- {
- flags = flags|EXTENDED_ID;
- }
- else
- {
- flags = flags|STANDARD_ID;
- }
-
-
- if(v.v_.is_fd())
- {
- flags = flags|FD_FRAME;
- }
-
o << gen(flags) << ",";
o << "frequency_clock_t(" << gen(v.v_.max_frequency()) << "),"
<< gen(v.v_.force_send_changed()) << ",";
std::uint32_t index = 0;
- o << "\n\t\t\t\t\t{ // beginning signals vector\n";
+ o << "\n\t\t\t{ // beginning signals vector\n";
std::uint32_t signal_count = (uint32_t)v.v_.signals().size();
for(const openxc::signal& s : v.v_.signals())
{
- o << gen(s, index,"\t\t\t\t\t\t");
+ o << gen(s, index,"\t\t\t\t");
if (signal_count > 1) o << ',';
--signal_count;
o << '\n';
}
- o << "\t\t\t\t\t} // end signals vector\n"
- << "\t\t\t\t})} // end message_definition entry\n";
+ o << "\t\t\t} // end signals vector\n"
+ << "\t\t})} // end message_definition entry\n";
return o;
}
@@ -283,56 +290,33 @@ std::ostream& operator<<(std::ostream& o, const generator<openxc::diagnostic_mes
/// @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 \"application.hpp\"\n"
- << "#include \"../can/can-decoder.hpp\"\n"
- << "#include \"../can/can-encoder.hpp\"\n\n";
+ // Derive CAPI name from message set name
+ // (the name is lowercased and spaces are converted to dashes ('-')
+ std::string capi_name(message_set.name());
+ std::transform(capi_name.begin(), capi_name.end(), capi_name.begin(),
+ [](unsigned char c){ return (c == ' ' ? '-' : std::tolower(c)); });
+
+ out << "#include <binding/application.hpp>\n"
+ << "#include <can/can-decoder.hpp>\n"
+ << "#include <can/can-encoder.hpp>\n\n";
if (header.size()) out << header << "\n";
- out << "application_t::application_t()\n"
- << " : can_bus_manager_{utils::config_parser_t{\"/etc/dev-mapping.conf\"}}\n"
- << " , message_set_{\n"
+ out << "extern \"C\" {\n"
+ << "CTLP_CAPI_REGISTER(\"" << capi_name << "\");\n"
+ << "\n"
<< gen(message_set, "\t\t")
- << "\t} // end message_set vector\n"
- << "{\n"
- << " for(std::shared_ptr<message_set_t> cms: message_set_)\n"
- << " {\n"
- << " std::vector<std::shared_ptr<message_definition_t>> messages_definition = cms->get_messages_definition();\n"
- << " for(std::shared_ptr<message_definition_t> cmd : messages_definition)\n"
- << " {\n"
- << " cmd->set_parent(cms);\n"
- << " std::vector<std::shared_ptr<signal_t>> signals = cmd->get_signals();\n"
- << " for(std::shared_ptr<signal_t> sig: signals)\n"
- << " {\n"
- << " sig->set_parent(cmd);\n"
- << " }\n"
- << " }\n\n"
- << " std::vector<std::shared_ptr<diagnostic_message_t>> diagnostic_messages = cms->get_diagnostic_messages();\n"
- << " for(std::shared_ptr<diagnostic_message_t> dm : diagnostic_messages)\n"
- << " {\n"
- << " dm->set_parent(cms);\n"
- << " }\n"
- << " }\n"
- << " }\n\n"
- << "const std::string application_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 << "\treturn " << gen(active_bus) << ";\n"
- << "}\n\n";
-
+ << "\n"
+ << "CTLP_ONLOAD(plugin, handle) {\n"
+ << "\tafb_api_t api = (afb_api_t) plugin->api;\n"
+ << "\tCtlConfigT* CtlConfig = (CtlConfigT*) afb_api_get_userdata(api);\n"
+ << "\tapplication_t* app = (application_t*) getExternalData(CtlConfig);\n"
+ << "\n"
+ << "\treturn app->add_message_set(cms);\n"
+ << "}\n\n\n}\n";
out << decoder_t::apply_patch();
-
-
out << footer << std::endl;
}
diff --git a/src/main.hpp b/src/main.hpp
deleted file mode 100644
index cf08e1a..0000000
--- a/src/main.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015, 20"IoT.bzh"
- * Author "Romain Forlot" <romain.forlot@iot.bzh>
- *
- * 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/src/openxc/signal.cpp b/src/openxc/signal.cpp
index e60c3ee..858f64b 100755
--- a/src/openxc/signal.cpp
+++ b/src/openxc/signal.cpp
@@ -88,12 +88,14 @@ namespace openxc
return multiplex_;
}
- bool signal::is_big_endian() const{
- return is_big_endian_;
+ sign_t signal::sign() const
+ {
+ return sign_;
}
- bool signal::is_signed() const{
- return is_signed_;
+ std::int32_t signal::bit_sign_position() const
+ {
+ return bit_sign_position_;
}
std::string signal::unit() const{
@@ -134,11 +136,10 @@ namespace openxc
{
multiplex_ = std::make_pair(false,0);
}
- is_big_endian_ = j.count("is_big_endian") ? j["is_big_endian"].get<bool>() : false;
- is_signed_ = j.count("is_signed") ? j["is_signed"].get<bool>() : false;
- unit_ = j.count("unit") ? j["unit"].get<std::string>() : "";
-
+ bit_sign_position_ = j.count("bit_sign_position") ? j["bit_sign_position"].get<std::int32_t>() : -1;
+ sign_ = j.count("signed") ? (sign_t) j["signed"].get<std::uint32_t>() : sign_t::UNSIGNED;
+ unit_ = j.count("unit") ? j["unit"].get<std::string>() : "";
if (j.count("states"))
{
@@ -185,10 +186,8 @@ namespace openxc
j["multiplex"] = multi;
-
-
- j["is_big_endian"] = is_big_endian_;
- j["is_signed"] = is_signed_;
+ j["bit_sign_position"] = bit_sign_position_;
+ j["signed"] = static_cast<std::uint32_t>(sign_);
j["unit"] = unit_;
return j;
}
diff --git a/src/openxc/signal.hpp b/src/openxc/signal.hpp
index 750926b..ce0a2e1 100755
--- a/src/openxc/signal.hpp
+++ b/src/openxc/signal.hpp
@@ -8,27 +8,36 @@
namespace openxc
{
+ enum sign_t
+ {
+ UNSIGNED = 0,
+ SIGN_BIT = 1,
+ ONES_COMPLEMENT = 2,
+ TWOS_COMPLEMENT = 3,
+ SIGN_BIT_EXTERN = 4
+ };
+
class signal
{
private:
std::string id_;
std::string generic_name_;
- std::uint32_t bit_position_;
- std::uint32_t bit_size_;
+ std::uint32_t bit_position_;
+ std::uint32_t bit_size_;
float factor_;
float offset_;
std::string decoder_;
bool ignore_;
bool enabled_;
- std::map<std::string, std::vector<std::uint32_t>> states_;
+ std::map<std::string, std::vector<std::uint32_t>> states_;
float max_frequency_;
bool send_same_;
bool force_send_changed_;
bool writable_;
std::string encoder_;
- std::pair<bool,int> multiplex_;
- bool is_big_endian_;
- bool is_signed_;
+ std::pair<bool,int> multiplex_;
+ sign_t sign_;
+ std::int32_t bit_sign_position_;
std::string unit_;
public:
@@ -49,8 +58,8 @@ namespace openxc
bool writable() const;
std::string encoder() const;
std::pair<bool,int> multiplex() const;
- bool is_big_endian() const;
- bool is_signed() const;
+ sign_t sign() const;
+ std::int32_t bit_sign_position() const;
std::string unit() const;
void from_json(const nlohmann::json& j);