diff options
-rw-r--r-- | .gitmodules | 3 | ||||
m--------- | afb-utilities | 0 | ||||
-rw-r--r-- | conf.d/cmake/config.cmake | 8 | ||||
-rw-r--r-- | conf.d/project/etc/sources.json | 2 | ||||
-rw-r--r-- | controller/ctl-config.c | 4 | ||||
-rw-r--r-- | controller/ctl-plugin.c | 8 | ||||
m--------- | ctl-utilities | 0 | ||||
-rw-r--r-- | plugins/CMakeLists.txt | 6 | ||||
-rw-r--r-- | plugins/builtin.cpp | 17 | ||||
-rw-r--r-- | plugins/gps.c | 6 | ||||
-rw-r--r-- | plugins/low-can.cpp | 13 | ||||
-rw-r--r-- | signal-composer-binding/CMakeLists.txt | 3 | ||||
-rw-r--r-- | signal-composer-binding/signal-composer-binding.cpp | 2 | ||||
-rw-r--r-- | signal-composer-binding/signal-composer.cpp | 164 | ||||
-rw-r--r-- | signal-composer-binding/signal-composer.hpp | 12 | ||||
-rw-r--r-- | signal-composer-binding/signal.cpp | 30 | ||||
-rw-r--r-- | signal-composer-binding/signal.hpp | 5 | ||||
-rw-r--r-- | signal-composer-binding/source.cpp | 51 | ||||
-rw-r--r-- | signal-composer-binding/source.hpp | 4 |
19 files changed, 208 insertions, 130 deletions
diff --git a/.gitmodules b/.gitmodules index 27a02f2..823faa5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "conf.d/app-templates"] path = conf.d/app-templates url = https://gerrit.automotivelinux.org/gerrit/apps/app-templates +[submodule "ctl-utilities"] + path = ctl-utilities + url = git@github.com:fulup-bzh/ctl-utilities.git diff --git a/afb-utilities b/afb-utilities -Subproject 49a99fef3e1e1ea0ecd7f131fd56da4c54bcd14 +Subproject 77c12fc3a44ce4fd1f4a83019547190d0f44549 diff --git a/conf.d/cmake/config.cmake b/conf.d/cmake/config.cmake index 86831e8..77102a3 100644 --- a/conf.d/cmake/config.cmake +++ b/conf.d/cmake/config.cmake @@ -128,8 +128,10 @@ list(APPEND link_libraries afb-utilities lua-lib) # -O2 # CACHE STRING "Compilation flags for RELEASE build type.") -add_definitions("-DCONTROL_SUPPORT_LUA=1") -add_definitions("-DCTL_PLUGIN_MAGIC=3286576532") +add_definitions(-DCONTROL_PLUGIN_PATH="${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/lib/plugins") +add_definitions(-DCONTROL_CONFIG_PATH="${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/etc") +add_definitions(-DCONTROL_SUPPORT_LUA=1) +add_definitions(-DCTL_PLUGIN_MAGIC=3286576532) # (BUG!!!) as PKG_CONFIG_PATH does not work [should be an env variable] # --------------------------------------------------------------------- @@ -139,7 +141,7 @@ set(LD_LIBRARY_PATH ${CMAKE_INSTALL_PREFIX}/lib64 ${CMAKE_INSTALL_PREFIX}/lib) # Optional location for config.xml.in # ----------------------------------- #set(WIDGET_ICON conf.d/wgt/${PROJECT_ICON} CACHE PATH "Path to the widget icon") -#set(WIDGET_CONFIG_TEMPLATE ${CMAKE_CURRENT_SOURCE_DIR}/conf.d/wgt/config.xml.in CACHE PATH "Path to widget config file template (config.xml.in)") +set(WIDGET_CONFIG_TEMPLATE "${CMAKE_SOURCE_DIR}/conf.d/wgt/config.xml.in" CACHE PATH "Path to widget config file template (config.xml.in)") # Mandatory widget Mimetype specification of the main unit # -------------------------------------------------------------------------- diff --git a/conf.d/project/etc/sources.json b/conf.d/project/etc/sources.json index 0d04880..84a39fa 100644 --- a/conf.d/project/etc/sources.json +++ b/conf.d/project/etc/sources.json @@ -2,7 +2,7 @@ "$schema": "http://iot.bzh/download/public/schema/json/signal-composer-schema.json", "sources": [ { - "uid": "-serviceCAN", + "uid": "CAN-service", "api": "low-can", "info": "Low level binding to handle CAN bus communications", "getSignals": { diff --git a/controller/ctl-config.c b/controller/ctl-config.c index fe76c90..cf24057 100644 --- a/controller/ctl-config.c +++ b/controller/ctl-config.c @@ -35,7 +35,7 @@ char* CtlConfigSearch(const char *dirList, const char* fileName) { strncpy(controlFile, fileName, CONTROL_MAXPATH_LEN); } else { strncpy(controlFile, CONTROL_CONFIG_PRE "-", CONTROL_MAXPATH_LEN); - strncat(controlFile, GetBinderName(), CONTROL_MAXPATH_LEN); + strncat(controlFile, GetBinderName(), strlen(GetBinderName())); // Only possible because returned GetBinderName value is a static variable. } // search for default dispatch config file @@ -56,7 +56,7 @@ char* CtlConfigSearch(const char *dirList, const char* fileName) { if (index == 0) { if (strcasestr(filename, controlFile)) { char filepath[CONTROL_MAXPATH_LEN]; - strncpy(filepath, fullpath, sizeof (filepath)); + strncpy(filepath, fullpath, strlen(fullpath)); strncat(filepath, "/", strlen("/")); strncat(filepath, filename, strlen(filename)); return (strdup(filepath)); diff --git a/controller/ctl-plugin.c b/controller/ctl-plugin.c index 9a34a29..62fdb8b 100644 --- a/controller/ctl-plugin.c +++ b/controller/ctl-plugin.c @@ -18,7 +18,7 @@ * Json load using json_unpack https://jansson.readthedocs.io/en/2.9/apiref.html#parsing-and-validating-values */ - #define _GNU_SOURCE +#define _GNU_SOURCE #include <string.h> #include <dlfcn.h> #include <link.h> @@ -126,9 +126,9 @@ STATIC int PluginLoadOne (CtlPluginT *ctlPlugin, json_object *pluginJ, void* han } char pluginpath[CONTROL_MAXPATH_LEN]; - strncpy(pluginpath, fullpath, sizeof (pluginpath)); - strncat(pluginpath, "/", sizeof (pluginpath)); - strncat(pluginpath, filename, sizeof (pluginpath)); + strncpy(pluginpath, fullpath, strlen(fullpath)); + strncat(pluginpath, "/", strlen("/")); + strncat(pluginpath, filename, strlen(filename)); dlHandle = dlopen(pluginpath, RTLD_NOW); if (!dlHandle) { AFB_ERROR("CTL-PLUGIN-LOADONE Fail to load pluginpath=%s err= %s", pluginpath, dlerror()); diff --git a/ctl-utilities b/ctl-utilities new file mode 160000 +Subproject 34bc4deaf165e006cb8f4b9510b8bf25bbbd968 diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 1776cf9..b6eec08 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -35,7 +35,7 @@ PROJECT_TARGET_ADD(builtin) ) target_include_directories(${TARGET_NAME} - PRIVATE "../controller" + PRIVATE "../ctl-utilities/ctl-lib" PRIVATE "../signal-composer-binding") PROJECT_TARGET_ADD(low-can) @@ -57,7 +57,7 @@ PROJECT_TARGET_ADD(low-can) ) target_include_directories(${TARGET_NAME} - PRIVATE "../controller" + PRIVATE "../ctl-utilities/ctl-lib" PRIVATE "../signal-composer-binding") PROJECT_TARGET_ADD(gps) @@ -79,5 +79,5 @@ PROJECT_TARGET_ADD(gps) ) target_include_directories(${TARGET_NAME} - PRIVATE "../controller" + PRIVATE "../ctl-utilities/ctl-lib" PRIVATE "../signal-composer-binding") diff --git a/plugins/builtin.cpp b/plugins/builtin.cpp index e93d929..df6ba88 100644 --- a/plugins/builtin.cpp +++ b/plugins/builtin.cpp @@ -29,9 +29,7 @@ extern "C" { - -CTLP_LUALOAD -CTLP_REGISTER("builtin"); +CTLP_LUA_REGISTER("builtin"); static struct signalCBT* pluginCtx = NULL; @@ -40,18 +38,17 @@ CTLP_ONLOAD(plugin, handle) { pluginCtx = (struct signalCBT*)calloc (1, sizeof(struct signalCBT)); pluginCtx = (struct signalCBT*)handle; - AFB_NOTICE ("Low-can plugin: label='%s' version='%s' info='%s'", - plugin->label, - plugin->version, + AFB_NOTICE ("Low-can plugin: label='%s' info='%s'", + plugin->uid, plugin->info); return (void*)pluginCtx; } -CTLP_CAPI (defaultOnReceived, source, argsJ, eventJ, context) +CTLP_CAPI (defaultOnReceived, source, argsJ, eventJ) { struct signalCBT* ctx = (struct signalCBT*)source->context; - AFB_NOTICE("source: %s argj: %s, eventJ %s", source->label, + AFB_NOTICE("source: %s argj: %s, eventJ %s", source->uid, json_object_to_json_string(argsJ), json_object_to_json_string(eventJ)); void* sig = ctx->aSignal; @@ -70,7 +67,7 @@ CTLP_CAPI (defaultOnReceived, source, argsJ, eventJ, context) return 0; } -CTLP_LUA2C (setSignalValueWrap, label, argsJ) +CTLP_LUA2C (setSignalValueWrap, source, argsJ, responseJ) { const char* name = nullptr; double resultNum; @@ -80,7 +77,7 @@ CTLP_LUA2C (setSignalValueWrap, label, argsJ) "value", &resultNum, "timestamp", ×tamp)) { - AFB_ERROR("Fail to set value for label: %s, argsJ: %s", label, json_object_to_json_string(argsJ)); + AFB_ERROR("Fail to set value for uid: %s, argsJ: %s", source->uid, json_object_to_json_string(argsJ)); return -1; } struct signalValue result = resultNum; diff --git a/plugins/gps.c b/plugins/gps.c index 39b1f49..2aab040 100644 --- a/plugins/gps.c +++ b/plugins/gps.c @@ -28,15 +28,15 @@ #include "ctl-plugin.h" #include "wrap-json.h" -CTLP_REGISTER("gps"); +CTLP_LUA_REGISTER("gps"); // Call at initialisation time CTLP_ONLOAD(plugin, api) { - AFB_NOTICE ("GPS plugin: label='%s' version='%s' info='%s'", plugin->label, plugin->version, plugin->info); + AFB_NOTICE ("GPS plugin: uid='%s' 'info='%s'", plugin->uid, plugin->info); return api; } -CTLP_CAPI (subscribeToLow, source, argsJ, eventJ, context) { +CTLP_CAPI (subscribeToLow, source, argsJ, eventJ) { json_object* subscribeArgsJ = NULL, *responseJ = NULL; int err = 0; diff --git a/plugins/low-can.cpp b/plugins/low-can.cpp index a425296..8d09eda 100644 --- a/plugins/low-can.cpp +++ b/plugins/low-can.cpp @@ -31,7 +31,7 @@ extern "C" { -CTLP_REGISTER("low-can"); +CTLP_CAPI_REGISTER("low-can"); typedef struct { bool door; @@ -66,15 +66,14 @@ CTLP_ONLOAD(plugin, composerHandle) pluginCtx->pluginHandle = (struct signalCBT*)composerHandle; pluginCtx->subscriptionBatch = json_object_new_array(); - AFB_NOTICE ("Low-can plugin: label='%s' version='%s' info='%s'", - plugin->label, - plugin->version, + AFB_NOTICE ("Low-can plugin: label='%s' info='%s'", + plugin->uid, plugin->info); return (void*)pluginCtx; } -CTLP_CAPI (subscribeToLow, source, argsJ, eventJ, context) { +CTLP_CAPI (subscribeToLow, source, argsJ, eventJ) { lowCANCtxT *pluginCtx = (lowCANCtxT*)source->context; json_object* dependsArrayJ = nullptr, *subscribeArgsJ = nullptr, *subscribeFilterJ = nullptr, *responseJ = nullptr, *filterJ = nullptr; const char *id = nullptr, *event = nullptr, *unit = nullptr; @@ -125,7 +124,7 @@ CTLP_CAPI (subscribeToLow, source, argsJ, eventJ, context) { return err; } -CTLP_CAPI (isOpen, source, argsJ, eventJ, context) { +CTLP_CAPI (isOpen, source, argsJ, eventJ) { const char *eventName = nullptr; int eventStatus; uint64_t timestamp; @@ -168,7 +167,7 @@ CTLP_CAPI (isOpen, source, argsJ, eventJ, context) { } AFB_DEBUG("This is the situation: source:%s, args:%s, event:%s,\n fld: %s, flw: %s, frd: %s, frw: %s, rld: %s, rlw: %s, rrd: %s, rrw: %s", - source->label, + source->uid, json_object_to_json_string(argsJ), json_object_to_json_string(eventJ), pluginCtx->allDoorsCtx.front_left.door ? "true":"false", diff --git a/signal-composer-binding/CMakeLists.txt b/signal-composer-binding/CMakeLists.txt index c4eebfd..72177a4 100644 --- a/signal-composer-binding/CMakeLists.txt +++ b/signal-composer-binding/CMakeLists.txt @@ -37,6 +37,7 @@ PROJECT_TARGET_ADD(signal-composer) # Library dependencies (include updates automatically) TARGET_LINK_LIBRARIES(${TARGET_NAME} - afb-controller + #afb-controller + ctl-utilities ${link_libraries} ) diff --git a/signal-composer-binding/signal-composer-binding.cpp b/signal-composer-binding/signal-composer-binding.cpp index 5d2667d..bf40b2f 100644 --- a/signal-composer-binding/signal-composer-binding.cpp +++ b/signal-composer-binding/signal-composer-binding.cpp @@ -237,7 +237,7 @@ int execConf() { Composer& composer = Composer::instance(); int err = 0; - CtlConfigExec(composer.ctlConfig()); + CtlConfigExec(nullptr, composer.ctlConfig()); std::vector<std::shared_ptr<Signal>> allSignals = composer.getAllSignals(); ssize_t sigCount = allSignals.size(); for( std::shared_ptr<Signal>& sig: allSignals) diff --git a/signal-composer-binding/signal-composer.cpp b/signal-composer-binding/signal-composer.cpp index 2a689f8..5eb970e 100644 --- a/signal-composer-binding/signal-composer.cpp +++ b/signal-composer-binding/signal-composer.cpp @@ -45,6 +45,14 @@ bool startsWith(const std::string& str, const std::string& pattern) return false; } +void extractString(void* closure, json_object* object) +{ + std::vector<std::string> *files = (std::vector<std::string>*) closure; + const char *oneFile = json_object_get_string(object); + + files->push_back(oneFile); +} + // aSignal member value will be initialized in sourceAPI->addSignal() static struct signalCBT pluginHandle = { .searchNsetSignalValue = searchNsetSignalValueHandle, @@ -53,18 +61,22 @@ static struct signalCBT pluginHandle = { }; CtlSectionT Composer::ctlSections_[] = { - [0]={.key="plugins" , .label = "plugins", .info=nullptr, + [0]={.key="plugins" , .uid="plugins", .info=nullptr, .loadCB=pluginsLoad, - .handle=&pluginHandle}, - [1]={.key="sources" , .label = "sources", .info=nullptr, + .handle=&pluginHandle, + .actions=nullptr}, + [1]={.key="sources" , .uid="sources", .info=nullptr, .loadCB=loadSourcesAPI, - .handle=nullptr}, - [2]={.key="signals" , .label= "signals", .info=nullptr, + .handle=nullptr, + .actions=nullptr}, + [2]={.key="signals" , .uid="signals", .info=nullptr, .loadCB=loadSignals, - .handle=nullptr}, - [3]={.key=nullptr, .label=nullptr, .info=nullptr, + .handle=nullptr, + .actions=nullptr}, + [3]={.key=nullptr, .uid=nullptr, .info=nullptr, .loadCB=nullptr, - .handle=nullptr} + .handle=nullptr, + .actions=nullptr} }; /////////////////////////////////////////////////////////////////////////////// @@ -81,21 +93,22 @@ Composer::~Composer() CtlActionT* Composer::convert2Action(const std::string& name, json_object* actionJ) { - json_object *functionArgsJ = nullptr, *action = nullptr; + json_object *functionArgsJ = nullptr, *ctlActionJ = nullptr; char *function; const char *plugin; + CtlActionT *ctlAction = nullptr; if(actionJ && !wrap_json_unpack(actionJ, "{ss,s?s,s?o !}", "function", &function, "plugin", &plugin, "args", &functionArgsJ)) { - action = nullptr; + ctlActionJ = nullptr; if(startsWith(function, "lua://")) { std::string fName = std::string(function).substr(6); - wrap_json_pack(&action, "{ss,ss,so*}", - "label", name.c_str(), + wrap_json_pack(&ctlActionJ, "{ss,ss,so*}", + "uid", name.c_str(), "lua", fName.c_str(), "args", functionArgsJ); } @@ -108,8 +121,8 @@ CtlActionT* Composer::convert2Action(const std::string& name, json_object* actio AFB_ERROR("Miss something in uri either plugin name or function name. Uri has to be like: api://<plugin-name>/<function-name>"); return nullptr; } - wrap_json_pack(&action, "{ss,ss,ss,so*}", - "label", name.c_str(), + wrap_json_pack(&ctlActionJ, "{ss,ss,ss,so*}", + "uid", name.c_str(), "api", uriV[0].c_str(), "verb", uriV[1].c_str(), "args", functionArgsJ); @@ -128,8 +141,8 @@ CtlActionT* Composer::convert2Action(const std::string& name, json_object* actio "plugin", uriV[0].c_str(), "function", uriV[1].c_str(), "args", functionArgsJ); - wrap_json_pack(&action, "{ss,so}", - "label", name.c_str(), + wrap_json_pack(&ctlActionJ, "{ss,so}", + "uid", name.c_str(), "callback", callbackJ); } else if(startsWith(function, "builtin://")) @@ -143,8 +156,8 @@ CtlActionT* Composer::convert2Action(const std::string& name, json_object* actio "plugin", "builtin", "function", uriV[0].c_str(), "args", functionArgsJ); - wrap_json_pack(&action, "{ss,so}", - "label", name.c_str(), + wrap_json_pack(&ctlActionJ, "{ss,so}", + "uid", name.c_str(), "callback", callbackJ); } else @@ -153,8 +166,30 @@ CtlActionT* Composer::convert2Action(const std::string& name, json_object* actio return nullptr; } } - if(action) {return ActionLoad(action);} - return nullptr; + + if(ctlActionJ) + {ActionLoadOne(nullptr, ctlAction, ctlActionJ, 0);} + + return ctlAction; +} + +void Composer::loadAdditionnalFiles(json_object* filesJ) +{ + std::vector<std::string> files; + if(filesJ) + { + wrap_json_optarray_for_all(filesJ, extractString, (void*)&files); + if(! files.empty()) + { + for(const auto& oneFile: files) + { + std::string filepath = CtlConfigSearch(nullptr, CONTROL_CONFIG_PATH, oneFile.c_str()); + json_object* oneFileJ = json_object_from_file(filepath.c_str()); + if(oneFileJ) + {loadSourcesAPI(nullptr, nullptr, oneFileJ);} + } + } + } } /// @brief Add the builtin plugin in the default plugins section definition @@ -164,14 +199,14 @@ CtlActionT* Composer::convert2Action(const std::string& name, json_object* actio /// JSON configuration file. /// /// @return 0 if OK, other if not. -int Composer::pluginsLoad(CtlSectionT *section, json_object *pluginsJ) +int Composer::pluginsLoad(AFB_ApiT apiHandle, CtlSectionT *section, json_object *pluginsJ) { json_object* builtinJ = nullptr, * completePluginsJ = nullptr; if(pluginsJ) { wrap_json_pack(&builtinJ, "{ss,ss,ss,ss,s[s]}", - "label", "builtin", + "uid", "builtin", "version", "4.99", "info", "Builtin routine for onReceived or getSignals routines", "basename", "builtin", @@ -190,28 +225,31 @@ int Composer::pluginsLoad(CtlSectionT *section, json_object *pluginsJ) } } - return PluginConfig(section, completePluginsJ); + return PluginConfig(nullptr, section, completePluginsJ); } int Composer::loadOneSourceAPI(json_object* sourceJ) { json_object *initJ = nullptr, *getSignalsJ = nullptr, - *onReceivedJ = nullptr; + *onReceivedJ = nullptr, + *filesJ = nullptr; CtlActionT *initCtl = nullptr, *getSignalsCtl = nullptr, *onReceivedCtl = nullptr; const char *api, *info; int retention = 0; - int err = wrap_json_unpack(sourceJ, "{ss,s?s,s?o,s?o,s?o, s?i !}", + int err = wrap_json_unpack(sourceJ, "{ss,s?s,s?o,s?o,s?o,s?i,s?o !}", "api", &api, "info", &info, "init", &initJ, "getSignals", &getSignalsJ, // Signals field to make signals conf by sources "onReceived", &onReceivedJ, - "retention", &retention); + "retention", &retention, + // External files to load where lies others sources obj + "files", &filesJ); if (err) { AFB_ERROR("Missing something api|[info]|[init]|[getSignals] in %s", json_object_get_string(sourceJ)); @@ -240,10 +278,12 @@ int Composer::loadOneSourceAPI(json_object* sourceJ) sourcesListV_.push_back(std::make_shared<SourceAPI>(api, info, initCtl, getSignalsCtl, onReceivedCtl, retention)); + loadAdditionnalFiles(filesJ); + return err; } -int Composer::loadSourcesAPI(CtlSectionT* section, json_object *sourcesJ) +int Composer::loadSourcesAPI(AFB_ApiT apihandle, CtlSectionT* section, json_object *sourcesJ) { int err = 0; Composer& composer = instance(); @@ -276,7 +316,7 @@ int Composer::loadSourcesAPI(CtlSectionT* section, json_object *sourcesJ) } } else - {err += Composer::instance().initSourcesAPI();} + {Composer::instance().initSourcesAPI();} return err; } @@ -285,7 +325,8 @@ int Composer::loadOneSignal(json_object* signalJ) { json_object *onReceivedJ = nullptr, *dependsJ = nullptr, - *getSignalsArgs = nullptr; + *getSignalsArgs = nullptr, + *filesJ = nullptr; CtlActionT* onReceivedCtl; const char *id = nullptr, *event = nullptr, @@ -304,7 +345,9 @@ int Composer::loadOneSignal(json_object* signalJ) "retention", &retention, "unit", &unit, "frequency", &frequency, - "onReceived", &onReceivedJ); + "onReceived", &onReceivedJ, + // External files to load where lies others sources obj + "files", &filesJ); if (err) { AFB_ERROR("Missing something id|[event|depends]|[getSignalsArgs]|[retention]|[unit]|[frequency]|[onReceived] in %s", json_object_get_string(signalJ)); @@ -374,28 +417,30 @@ int Composer::loadOneSignal(json_object* signalJ) unit = !unit ? "" : unit; // Set default onReceived action if not specified - char* label = strndup("onReceived_", 11); - label = strncat(label, id, strlen(id)); + char* uid = strndup("onReceived_", 11); + uid = strncat(uid, id, strlen(id)); if(!onReceivedJ) { onReceivedCtl = src->signalsDefault().onReceived ? src->signalsDefault().onReceived : nullptr; - // Overwrite label to the signal one instead of the default + // Overwrite uid to the signal one instead of the default if(onReceivedCtl) - {onReceivedCtl->source.label = label;} + {onReceivedCtl->uid = uid;} } - else {onReceivedCtl = convert2Action(label, onReceivedJ);} + else {onReceivedCtl = convert2Action(uid, onReceivedJ);} if(src != nullptr) {src->addSignal(id, event, dependsV, retention, unit, frequency, onReceivedCtl, getSignalsArgs);} else {err = -1;} + loadAdditionnalFiles(filesJ); + return err; } -int Composer::loadSignals(CtlSectionT* section, json_object *signalsJ) +int Composer::loadSignals(AFB_ApiT apihandle, CtlSectionT* section, json_object *signalsJ) { int err = 0; Composer& composer = instance(); @@ -528,14 +573,41 @@ std::vector<std::string> Composer::parseURI(const std::string& uri) int Composer::loadConfig(const std::string& filepath) { - ctlConfig_ = CtlConfigLoad(filepath.c_str(), ctlSections_); - if(ctlConfig_ != nullptr) {return 0;} - return -1; + const char *dirList= getenv("CONTROL_CONFIG_PATH"); + if (!dirList) dirList=CONTROL_CONFIG_PATH; + const char *configPath = CtlConfigSearch (nullptr, dirList, "control-"); + + if (!configPath) { + AFB_ApiError(apiHandle, "CtlPreInit: No control-* config found invalid JSON %s ", dirList); + return -1; + } + + // create one API per file + ctlConfig_ = CtlLoadMetaData(nullptr, configPath); + if (!ctlConfig_) { + AFB_ApiError(apiHandle, "CtrlPreInit No valid control config file in:\n-- %s", configPath); + return -1; + } + + if (ctlConfig_->api) { + int err = afb_daemon_rename_api(ctlConfig_->api); + if (err) { + AFB_ApiError(apiHandle, "Fail to rename api to:%s", ctlConfig_->api); + return -1; + } + } + + int err= CtlLoadSections(nullptr, ctlConfig_, ctlSections_); + return err; + +// ctlConfig_ = CtlConfigLoad(filepath.c_str(), ctlSections_); +// if(ctlConfig_ != nullptr) {return 0;} +// return -1; } int Composer::loadSignals(json_object* signalsJ) { - return loadSignals(nullptr, signalsJ); + return loadSignals(nullptr, nullptr, signalsJ); } CtlConfigT* Composer::ctlConfig() @@ -543,14 +615,12 @@ CtlConfigT* Composer::ctlConfig() return ctlConfig_; } -int Composer::initSourcesAPI() +void Composer::initSourcesAPI() { - int err = 0; for(auto& src: sourcesListV_) { - err += src->init(); + src->init(); } - return err; } std::shared_ptr<SourceAPI> Composer::getSourceAPI(const std::string& api) @@ -649,15 +719,13 @@ json_object* Composer::getsignalValue(const std::string& sig, json_object* optio return finalResponse; } -int Composer::execSignalsSubscription() +void Composer::execSignalsSubscription() { - int err = 0; for(std::shared_ptr<SourceAPI> srcAPI: sourcesListV_) { if (srcAPI->api() != std::string(ctlConfig_->api)) { - err = srcAPI->makeSubscription(); + srcAPI->makeSubscription(); } } - return err; } diff --git a/signal-composer-binding/signal-composer.hpp b/signal-composer-binding/signal-composer.hpp index 024336b..cd9c28f 100644 --- a/signal-composer-binding/signal-composer.hpp +++ b/signal-composer-binding/signal-composer.hpp @@ -18,7 +18,6 @@ #include <vector> #include <string> - #include "source.hpp" class Composer @@ -34,15 +33,16 @@ private: ~Composer(); CtlActionT* convert2Action(const std::string& name, json_object* action); - static int pluginsLoad(CtlSectionT *section, json_object *pluginsJ); + void loadAdditionnalFiles(json_object* filesJ); + static int pluginsLoad(AFB_ApiT apiHandle, CtlSectionT *section, json_object *pluginsJ); int loadOneSourceAPI(json_object* sourcesJ); - static int loadSourcesAPI(CtlSectionT* section, json_object *signalsJ); + static int loadSourcesAPI(AFB_ApiT apihandle, CtlSectionT* section, json_object *signalsJ); int loadOneSignal(json_object* signalsJ); - static int loadSignals(CtlSectionT* section, json_object *signalsJ); + static int loadSignals(AFB_ApiT apihandle, CtlSectionT* section, json_object *signalsJ); - int initSourcesAPI(); + void initSourcesAPI(); std::shared_ptr<SourceAPI> getSourceAPI(const std::string& api); void processOptions(const std::map<std::string, int>& opts, std::shared_ptr<Signal> sig, json_object* response) const; public: @@ -58,5 +58,5 @@ public: std::vector<std::shared_ptr<Signal>> searchSignals(const std::string& aName); json_object* getsignalValue(const std::string& sig, json_object* options); - int execSignalsSubscription(); + void execSignalsSubscription(); }; diff --git a/signal-composer-binding/signal.cpp b/signal-composer-binding/signal.cpp index df0ca00..e099c43 100644 --- a/signal-composer-binding/signal.cpp +++ b/signal-composer-binding/signal.cpp @@ -140,6 +140,19 @@ json_object* Signal::toJSON() const return queryJ; } +struct signalCBT* Signal::get_context() +{ + struct signalCBT* ctx = (struct signalCBT*)calloc (1, sizeof(struct signalCBT)); + + if(!ctx->searchNsetSignalValue) + {ctx->searchNsetSignalValue = searchNsetSignalValueHandle;} + if(!ctx->setSignalValue) + {ctx->setSignalValue = setSignalValueHandle;} + + ctx->aSignal = (void*)this; + return ctx; +} + /// @brief Set Signal timestamp and value property when an incoming /// signal arrived. Called by a plugin because treatment can't be /// standard as signals sources format could changes. See low-can plugin @@ -176,7 +189,7 @@ void Signal::update(Signal* sig) /// @param[in] eventJ - json_object containing event data to process /// /// @return 0 if ok, -1 or others if not -int Signal::defaultReceivedCB(json_object *eventJ) +void Signal::defaultReceivedCB(json_object *eventJ) { uint64_t ts = 0; struct signalValue sv; @@ -206,7 +219,7 @@ int Signal::defaultReceivedCB(json_object *eventJ) if(!sv.hasBool && !sv.hasNum && !sv.hasStr) { AFB_ERROR("No data found to set signal %s in %s", id_.c_str(), json_object_to_json_string(eventJ)); - return -1; + return; } else if(ts == 0) { @@ -216,7 +229,6 @@ int Signal::defaultReceivedCB(json_object *eventJ) } set(ts, sv); - return 0; } /// @brief Notify observers that there is a change and execute callback defined @@ -224,8 +236,7 @@ int Signal::defaultReceivedCB(json_object *eventJ) /// /// @param[in] eventJ - JSON query object to transmit to callback function /// -/// @return 0 if OK, -1 or other if not. -int Signal::onReceivedCB(json_object *eventJ) +void Signal::onReceivedCB(json_object *eventJ) { if(onReceived_ && onReceived_->type == CTL_TYPE_LUA) { @@ -246,9 +257,14 @@ int Signal::onReceivedCB(json_object *eventJ) json_object_iter_next(&iter); } } - int err = onReceived_ ? ActionExecOne(onReceived_, eventJ) : defaultReceivedCB(eventJ); + + CtlSourceT source; + source.uid = id_.c_str(); + source.api = nullptr; // We use binding v2, no dynamic API. + source.request = {nullptr, nullptr}; + source.context = (void*)get_context(); + onReceived_ ? ActionExecOne(&source, onReceived_, eventJ) : defaultReceivedCB(eventJ); notify(); - return err; } /// @brief Make a Signal observer observes Signals observables diff --git a/signal-composer-binding/signal.hpp b/signal-composer-binding/signal.hpp index ba3e8c7..97ab4c7 100644 --- a/signal-composer-binding/signal.hpp +++ b/signal-composer-binding/signal.hpp @@ -87,12 +87,13 @@ public: const std::string id() const; json_object* toJSON() const; + struct signalCBT* get_context(); void set(uint64_t timestamp, struct signalValue& value); void update(Signal* sig); static int defaultOnReceivedCB(CtlSourceT* source, json_object* argsJ, json_object *queryJ); - int defaultReceivedCB(json_object *queryJ); - int onReceivedCB(json_object *queryJ); + void defaultReceivedCB(json_object *eventJ); + void onReceivedCB(json_object *eventJ); void attachToSourceSignals(Composer& composer); double average(int seconds = 0) const; diff --git a/signal-composer-binding/source.cpp b/signal-composer-binding/source.cpp index 4511fa7..3e8153a 100644 --- a/signal-composer-binding/source.cpp +++ b/signal-composer-binding/source.cpp @@ -28,14 +28,19 @@ SourceAPI::SourceAPI(const std::string& api, const std::string& info, CtlActionT signalsDefault_({onReceived, retention}) {} -int SourceAPI::init() +void SourceAPI::init() { if(init_) - {return ActionExecOne(init_, nullptr);} + { + CtlSourceT source; + source.uid = init_->uid; + source.api = nullptr; // We use binding v2, no dynamic API. + source.request = {nullptr, nullptr}; + ActionExecOne(&source, init_, nullptr); + return; + } else if(api_ == afbBindingV2.api) {api_ = Composer::instance().ctlConfig()->api;} - - return 0; } std::string SourceAPI::api() const @@ -52,20 +57,6 @@ void SourceAPI::addSignal(const std::string& id, const std::string& event, std:: { std::shared_ptr<Signal> sig = std::make_shared<Signal>(id, event, depends, unit, retention, frequency, onReceived, getSignalsArgs); - if(onReceived) - { - struct signalCBT* ctx = onReceived->source.context ? - (struct signalCBT*)onReceived->source.context : - (struct signalCBT*)calloc (1, sizeof(struct signalCBT)); - if(!ctx->searchNsetSignalValue) - {ctx->searchNsetSignalValue = searchNsetSignalValueHandle;} - if(!ctx->setSignalValue) - {ctx->setSignalValue = setSignalValueHandle;} - - ctx->aSignal = (void*)sig.get(); - onReceived->source.context = (void*)ctx; - } - signalsMap_[id] = sig; } @@ -104,29 +95,29 @@ std::vector<std::shared_ptr<Signal>> SourceAPI::searchSignals(const std::string& return signals; } -int SourceAPI::makeSubscription() +void SourceAPI::makeSubscription() { - int err = 0; if(getSignals_) { + CtlSourceT source; + source.uid = api_.c_str(); + source.api = nullptr; // We use binding v2, no dynamic API. + source.request = {nullptr, nullptr}; + for(auto& sig: signalsMap_) { json_object* signalJ = sig.second->toJSON(); if(!signalJ) { AFB_ERROR("Error building JSON query object to subscribe to for signal %s", sig.second->id().c_str()); - err = -1; break; } - err += ActionExecOne(getSignals_, signalJ); - if(err) - {AFB_WARNING("Fails to subscribe to signal '%s/%s'", - api_.c_str(), sig.second->id().c_str());} - else - {sig.second->subscribed_ = true;} + source.uid = sig.second->id().c_str(); + source.context = (void*)sig.second->get_context(); + ActionExecOne(&source, getSignals_, signalJ); + // Considerate signal subscribed no matter what + sig.second->subscribed_ = true; } - err += ActionExecOne(getSignals_, nullptr); + ActionExecOne(&source, getSignals_, nullptr); } - - return err; } diff --git a/signal-composer-binding/source.hpp b/signal-composer-binding/source.hpp index 6aacf4f..5c1e074 100644 --- a/signal-composer-binding/source.hpp +++ b/signal-composer-binding/source.hpp @@ -39,7 +39,7 @@ public: SourceAPI(); SourceAPI(const std::string& api, const std::string& info, CtlActionT* init, CtlActionT* getSignal, CtlActionT* onReceived, int retention); - int init(); + void init(); std::string api() const; const struct signalsDefault& signalsDefault() const; void addSignal(const std::string& id, const std::string& event, std::vector<std::string>& sources, int retention, const std::string& unit, double frequency, CtlActionT* onReceived, json_object* getSignalsArgs); @@ -47,5 +47,5 @@ public: std::vector<std::shared_ptr<Signal>> getSignals() const; std::vector<std::shared_ptr<Signal>> searchSignals(const std::string& name); - int makeSubscription(); + void makeSubscription(); }; |