Update to match current binding expectations 49/25349/1 sandbox/walzert/low-level-can-generator
authorScott Murray <scott.murray@konsulko.com>
Wed, 23 Sep 2020 20:07:53 +0000 (16:07 -0400)
committerScott Murray <scott.murray@konsulko.com>
Wed, 23 Sep 2020 20:25:30 +0000 (16:25 -0400)
Changes:
- Reworked header, footer, message structure definition, etc. to
  match the contents of the current generated files in the binding.
- To enable the above, added some code to derive the API name for
  the app controller CAPI macro from the name given for the message
  set in the JSON. The name is lower-cased and spaces converted to
  dashes, this matches all the examples in the generated files in
  the binding.
- Added logic to default message length to 8 if not set in JSON,
  this is required to match explicit checks and signal JSON changes
  in the binding.
- Replaced is_bigendian and is_signed fields with new sign and
  bit_sign_position fields in JSON parsing and generated signal
  output. The sign field value enum has been copied from the binding
  to provide a reference for the values.
- Update per-signal flags generation, to enable this updated flag
  #defines from binding's current can-message.hpp. Added a comment
  to document which flags are known to be used.
- Removed "package" from "all" target in Makefile, as it is attached
  to widget packaging rules that are not applicable for the
  generator, which is built for host or toolchain usage.
- Removed unused src/main.hpp header to avoid confusion.

Bug-AGL: SPEC-3551

Signed-off-by: Scott Murray <scott.murray@konsulko.com>
Change-Id: I9ef3df0ebcfbddc23c789b50e1575fc42031970d

Makefile
src/main.cpp
src/main.hpp [deleted file]
src/openxc/signal.cpp
src/openxc/signal.hpp

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