+
+/// @brief Initialize the binding.
+///
+/// @param[in] service Structure which represent the Application Framework Binder.
+///
+/// @return Exit code, zero if success.
+int init_binding(afb_api_t api)
+{
+ int ret = 1;
+ application_t& application = application_t::instance();
+ can_bus_t& can_bus_manager = application.get_can_bus_manager();
+
+ if(application.get_message_set().empty())
+ {
+ AFB_ERROR("No message_set defined");
+ return -1;
+ }
+
+ can_bus_manager.start_threads();
+ utils::signals_manager_t& sm = utils::signals_manager_t::instance();
+
+ // Add a recurring dignostic message request to get engine speed at all times.
+ openxc_DynamicField search_key = build_DynamicField("diagnostic_messages.engine.speed");
+ struct utils::signals_found sf = sm.find_signals(search_key);
+
+ if(sf.signals.empty() && sf.diagnostic_messages.size() == 1)
+ {
+ afb_req_t request = nullptr;
+
+ struct event_filter_t event_filter;
+ event_filter.frequency = sf.diagnostic_messages.front()->get_frequency();
+
+ map_subscription& s = sm.get_subscribed_signals();
+
+ subscribe_unsubscribe_diagnostic_messages(request, true, sf.diagnostic_messages, event_filter, s, true);
+ }
+
+
+#ifdef USE_FEATURE_J1939
+ std::string j1939_bus;
+ vect_ptr_msg_def_t current_messages_definition = application.get_messages_definition();
+ for(std::shared_ptr<message_definition_t> message_definition: current_messages_definition)
+ {
+ if(message_definition->is_j1939())
+ {
+ if (j1939_bus == message_definition->get_bus_device_name() )
+ continue;
+ j1939_bus = message_definition->get_bus_device_name();
+
+ std::shared_ptr<low_can_subscription_t> low_can_j1939 = std::make_shared<low_can_subscription_t>();
+ application.set_subscription_address_claiming(low_can_j1939);
+
+ ret = low_can_subscription_t::open_socket(*low_can_j1939,
+ j1939_bus,
+ J1939_ADDR_CLAIM_PROTOCOL);
+
+ if(ret < 0)
+ {
+ AFB_ERROR("Error open socket address claiming for j1939 protocol");
+ return -1;
+ }
+ add_to_event_loop(low_can_j1939);
+ break;
+ }
+ }
+#endif
+
+ if(ret)
+ AFB_ERROR("There was something wrong with CAN device Initialization.");
+
+ return ret;
+}
+
+int load_config(afb_api_t api)
+{
+ int ret = 0;
+ CtlConfigT *ctlConfig;
+ const char *dirList = getenv("CONTROL_CONFIG_PATH");
+ std::string bindingDirPath = GetBindingDirPath(api);
+ std::string filepath = bindingDirPath + "/etc";
+
+ if (!dirList)
+ dirList=CONTROL_CONFIG_PATH;
+
+ filepath.append(":");
+ filepath.append(dirList);
+ const char *configPath = CtlConfigSearch(api, filepath.c_str(), "control");
+
+ if (!configPath)
+ {
+ AFB_ERROR_V3("CtlPreInit: No control-* config found invalid JSON %s ", filepath.c_str());
+ return -1;
+ }
+
+ // create one API per file
+ ctlConfig = CtlLoadMetaData(api, configPath);
+ if (!ctlConfig)
+ {
+ AFB_ERROR_V3("CtrlPreInit No valid control config file in:\n-- %s", configPath);
+ return -1;
+ }
+
+ // Save the config in the api userdata field
+ afb_api_set_userdata(api, ctlConfig);
+
+ setExternalData(ctlConfig, (void*) &application_t::instance());
+ ret= CtlLoadSections(api, ctlConfig, ctlSections_);
+
+ return ret;
+}