aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Forlot <romain.forlot@iot.bzh>2017-11-02 15:58:45 +0100
committerRomain Forlot <romain.forlot@iot.bzh>2017-12-14 11:00:25 +0100
commit6ee4db6878464642ddf9f0909748841a45b58a88 (patch)
tree4c3588d216e903174f1281b757e98816d7323afa
parented2c3d0267e3c5e1392635dacad2752de935d6b4 (diff)
Migrate to ctl-utilities library
New version of controller as a library. Loading additionnals files from each sections. Change-Id: I4f5e78d0baf9650cb8d1cc1da26f8e1fd73b792c Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
-rw-r--r--.gitmodules3
m---------afb-utilities0
-rw-r--r--conf.d/cmake/config.cmake8
-rw-r--r--conf.d/project/etc/sources.json2
-rw-r--r--controller/ctl-config.c4
-rw-r--r--controller/ctl-plugin.c8
m---------ctl-utilities0
-rw-r--r--plugins/CMakeLists.txt6
-rw-r--r--plugins/builtin.cpp17
-rw-r--r--plugins/gps.c6
-rw-r--r--plugins/low-can.cpp13
-rw-r--r--signal-composer-binding/CMakeLists.txt3
-rw-r--r--signal-composer-binding/signal-composer-binding.cpp2
-rw-r--r--signal-composer-binding/signal-composer.cpp164
-rw-r--r--signal-composer-binding/signal-composer.hpp12
-rw-r--r--signal-composer-binding/signal.cpp30
-rw-r--r--signal-composer-binding/signal.hpp5
-rw-r--r--signal-composer-binding/source.cpp51
-rw-r--r--signal-composer-binding/source.hpp4
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", &timestamp))
{
- 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();
};