From cd2e830c37cfbeb353355c8ae5ed3b5c7973ed37 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Wed, 6 Jan 2021 18:30:03 -0500 Subject: Restore /etc/dev-mapping.conf support Add back the ini-config and config-parser code that existed previously, and use it in binding init to over-ride the device mapping from the controller JSON if /etc/dev-mapping.conf exists. This restores the documented behavior, and is needed for the existing AGL demo platform support and soon CI. Additionally: - Add code to validate the active_message_set, diagnostic_bus, and bus device mapping configuration values. - The above required moving plugin loading before the configuration callback in the controller configuration, but this change seems rational in that everything required by the generated plugin code is already initialized before then, and it makes validating the configuration possible without adding an extra callback. - Add logging of the used CAN bus to device mappings at info level to ease debugging any future issues. - Tweak the log level of the missing configuration file message to info from error, since it is a legitimate mode of operation if relying on the default bus values in the controller JSON. Bug-AGL: SPEC-3755 Signed-off-by: Scott Murray Change-Id: I440f5e0fc85be41f7c4c1f47d824a403525a18f9 (cherry picked from commit 9e23caa4c56259044604c38f107f7c637001b846) --- low-can-binding/binding/low-can-cb.cpp | 81 ++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 14 deletions(-) (limited to 'low-can-binding/binding') diff --git a/low-can-binding/binding/low-can-cb.cpp b/low-can-binding/binding/low-can-cb.cpp index d994dd24..32adac86 100644 --- a/low-can-binding/binding/low-can-cb.cpp +++ b/low-can-binding/binding/low-can-cb.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2015, 2018 "IoT.bzh" + * Copyright (C) 2021 Konsulko Group * Author "Romain Forlot" * Author "Loic Collignon" * @@ -23,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +39,7 @@ #include "../utils/signals.hpp" #include "../diagnostic/diagnostic-message.hpp" #include "../utils/openxc-utils.hpp" -#include "../utils/signals.hpp" +#include "../utils/config-parser.hpp" #ifdef USE_FEATURE_J1939 #include "../can/message/j1939-message.hpp" @@ -56,7 +58,7 @@ int config_low_can(afb_api_t apiHandle, CtlSectionT *section, json_object *json_ CtlConfigT *ctrlConfig = (CtlConfigT *) afb_api_get_userdata(apiHandle); int active_message_set = 0; json_object *dev_mapping = nullptr; - const char *diagnotic_bus = nullptr; + const char *diagnostic_bus = nullptr; if(! ctrlConfig || ! ctrlConfig->external) return -1; @@ -64,35 +66,86 @@ int config_low_can(afb_api_t apiHandle, CtlSectionT *section, json_object *json_ application_t *application = (application_t*) ctrlConfig->external; if(wrap_json_unpack(json_obj, "{si, s?s}", - "active_message_set", &active_message_set, - "diagnostic_bus", &diagnotic_bus)) + "active_message_set", &active_message_set, + "diagnostic_bus", &diagnostic_bus)) { + AFB_ERROR("active_message_set and/or diagnostic_bus missing in controller JSON"); + return -1; + } + + if(active_message_set < 0 || + active_message_set > (application->get_messages_definition().size() - 1)) { + AFB_ERROR("Invalid active message set %d", active_message_set); return -1; + } + application->set_active_message_set((uint8_t) active_message_set); + + utils::config_parser_t conf_file("/etc/dev-mapping.conf"); + if(conf_file.check_conf()) + { + // If a mapping file in /etc exists, use it + AFB_INFO("Using /etc/dev-mapping.conf"); + application->get_can_bus_manager().set_can_devices(conf_file.get_devices_name()); + } else { + // Use whatever configuration is in the controller JSON + if(wrap_json_unpack(json_obj, "{so}", + "dev-mapping", &dev_mapping)) { + AFB_ERROR("No device mapping in controller JSON"); + return -1; + } + + application->get_can_bus_manager().set_can_devices(dev_mapping); + } + + // Find all required buses + std::set buses; + std::set j1939_buses; + vect_ptr_msg_def_t msg_defs = application->get_messages_definition(); + for(std::shared_ptr &msg_def : msg_defs) { + if(!msg_def->is_j1939()) + buses.insert(msg_def->get_bus_name()); + else + j1939_buses.insert(msg_def->get_bus_name()); + } +#ifdef USE_FEATURE_J1939 + // NOTE: With C++17 just: buses.merge(j1939_buses) + for(auto it = begin(j1939_buses); it != end(j1939_buses); ++it) + buses.insert(*it); +#endif - application->set_active_message_set((uint8_t)active_message_set); + // Check that required buses have device mappings + for(auto it = begin(buses); it != end(buses); ++it) { + std::string dev = application->get_can_bus_manager().get_can_device_name(*it); + if(dev == "") { + AFB_ERROR("No CAN device defined for bus \"%s\"", it->c_str()); + return -1; + } + AFB_INFO("Using CAN device %s for bus \"%s\"", dev.c_str(), it->c_str()); + } - if(wrap_json_unpack(json_obj, "{so}", - "dev-mapping", &dev_mapping)) + // Check that diagnostic bus is one of the configured buses + if(diagnostic_bus && buses.count(diagnostic_bus) == 0) { + AFB_ERROR("No CAN device mapping defined for diagnostic bus \"%s\"", diagnostic_bus); return -1; - application->get_can_bus_manager().set_can_devices(dev_mapping); + } /// Initialize Diagnostic manager that will handle obd2 requests. /// We pass by default the first CAN bus device to its Initialization. - if(! diagnotic_bus || application_t::instance().get_diagnostic_manager().initialize(diagnotic_bus)) + if(! diagnostic_bus || application_t::instance().get_diagnostic_manager().initialize(diagnostic_bus)) AFB_WARNING("Diagnostic Manager: not initialized. No diagnostic messages will be processed."); return 0; } CtlSectionT ctlSections_[] = { - [0]={.key="config" , .uid="config", .info=nullptr, - .loadCB=config_low_can, - .handle=nullptr, - .actions=nullptr}, - [1]={.key="plugins" , .uid="plugins", .info=nullptr, + [0]={.key="plugins" , .uid="plugins", .info=nullptr, .loadCB=PluginConfig, .handle=nullptr, .actions=nullptr}, + [1]={.key="config" , .uid="config", .info=nullptr, + .loadCB=config_low_can, + .handle=nullptr, + .actions=nullptr}, [2]={.key=nullptr , .uid=nullptr, .info=nullptr, .loadCB=nullptr, .handle=nullptr, -- cgit 1.2.3-korg