summaryrefslogtreecommitdiffstats
path: root/signal-composer-binding/ctl-dispatch.c
diff options
context:
space:
mode:
authorRomain Forlot <romain.forlot@iot.bzh>2017-09-12 00:29:28 +0200
committerRomain Forlot <romain.forlot@iot.bzh>2017-12-14 11:00:25 +0100
commitd663f702c0e4fa562783504a483dce8f362d628e (patch)
treefdb656d0467a935aa6790dd9e05d3e373606a3e1 /signal-composer-binding/ctl-dispatch.c
parent75cfbf3d0206f12422091e6479c508c69445bf4a (diff)
Progression on config parsing.
Change-Id: Idd8d8987ccabef381f6d79c1d508930a2d4bae3c Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
Diffstat (limited to 'signal-composer-binding/ctl-dispatch.c')
-rw-r--r--signal-composer-binding/ctl-dispatch.c705
1 files changed, 0 insertions, 705 deletions
diff --git a/signal-composer-binding/ctl-dispatch.c b/signal-composer-binding/ctl-dispatch.c
deleted file mode 100644
index b84c86e..0000000
--- a/signal-composer-binding/ctl-dispatch.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (C) 2016 "IoT.bzh"
- * Author Fulup Ar Foll <fulup@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, something express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Reference:
- * Json load using json_unpack https://jansson.readthedocs.io/en/2.9/apiref.html#parsing-and-validating-values
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <dlfcn.h>
-#include <sys/prctl.h>
-#include <filescan-utils.h>
-#include <wrap-json.h>
-
-#include "ctl-lua.h"
-#include "signal-composer-binding.hpp"
-
-typedef void*(*DispatchPluginInstallCbT)(const char* label, const char*version, const char*info);
-
-static afb_req NULL_AFBREQ = {};
-
-typedef struct {
- const char* id;
- const char* source;
- const char* class;
- DispatchActionT* onReceived;
-} DispatchSignalT;
-
-typedef struct {
- const char* label;
- const char* info;
- const char* ssource;
- const char* sclass;
- DispatchActionT* actions;
-} DispatchHandleT;
-
-typedef struct {
- const char *label;
- const char *info;
- void *context;
- char *sharelib;
- void *dlHandle;
- luaL_Reg *l2cFunc;
- int l2cCount;
-} DispatchPluginT;
-
-typedef struct {
- const char* label;
- const char *info;
- const char *version;
- DispatchPluginT *plugin;
- DispatchHandleT **sources;
- DispatchHandleT **signals;
-} DispatchConfigT;
-
-// global config handle
-static DispatchConfigT *configHandle = NULL;
-
-static int DispatchSignalToIndex(DispatchHandleT **signals, const char* controlLabel) {
-
- for (int idx = 0; signals[idx]; idx++) {
- if (!strcasecmp(controlLabel, signals[idx]->label)) return idx;
- }
- return -1;
-}
-
-static int DispatchOneSignal(DispatchSourceT source, DispatchHandleT **signals, const char* controlLabel, json_object *queryJ, afb_req request) {
- int err;
-
- if (!configHandle) {
- AFB_ERROR("DISPATCH-CTL-API: (Hoops/Bug!!!) No Config Loaded");
- return -1;
- }
-
- if (!configHandle->signals) {
- AFB_ERROR("DISPATCH-CTL-API: No Signal Action in Json config label=%s version=%s", configHandle->label, configHandle->version);
- return -1;
- }
-
- int index = DispatchSignalToIndex(signals, controlLabel);
- if (index < 0 || !signals[index]->actions) {
- AFB_ERROR("DISPATCH-CTL-API:NotFound/Error label=%s in Json Signal Config File", controlLabel);
- return -1;
- }
-
- // Fulup (Bug/Feature) in current version is unique to every onload profile
- if (configHandle->plugin && configHandle->plugin->l2cCount) {
- LuaL2cNewLib (configHandle->plugin->label, configHandle->plugin->l2cFunc, configHandle->plugin->l2cCount);
- }
-
- // loop on action for this control
- DispatchActionT *actions = signals[index]->actions;
- for (int idx = 0; actions[idx].label; idx++) {
-
- switch (actions[idx].mode) {
- case CTL_MODE_API:
- {
- json_object *returnJ;
-
- // if query is empty increment usage count and pass args
- if (!queryJ || json_object_get_type(queryJ) != json_type_object) {
- json_object_get(actions[idx].argsJ);
- queryJ= actions[idx].argsJ;
- } else if (actions[idx].argsJ) {
-
- // Merge queryJ and argsJ before sending request
- if (json_object_get_type(actions[idx].argsJ) == json_type_object) {
- json_object_object_foreach(actions[idx].argsJ, key, val) {
- json_object_object_add(queryJ, key, val);
- }
- } else {
- json_object_object_add(queryJ, "args", actions[idx].argsJ);
- }
- }
-
- int err = afb_service_call_sync(actions[idx].api, actions[idx].call, queryJ, &returnJ);
- if (err) {
- static const char*format = "DispatchOneSignal(Api) api=%s verb=%s args=%s";
- if (afb_req_is_valid(request))afb_req_fail_f(request, "DISPATCH-CTL-MODE:API", format, actions[idx].label, actions[idx].api, actions[idx].call);
- else AFB_ERROR(format, actions[idx].api, actions[idx].call, actions[idx].label);
- return -1;
- }
- break;
- }
-
-#ifdef CONTROL_SUPPORT_LUA
- case CTL_MODE_LUA:
- err = LuaCallFunc(source, &actions[idx], queryJ);
- if (err) {
- static const char*format = "DispatchOneSignal(Lua) label=%s func=%s args=%s";
- if (afb_req_is_valid(request)) afb_req_fail_f(request, "DISPATCH-CTL-MODE:Lua", format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ));
- else AFB_ERROR(format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ));
- return -1;
- }
- break;
-#endif
-
- case CTL_MODE_CB:
- err = (*actions[idx].actionCB) (source, actions[idx].label, actions[idx].argsJ, queryJ, configHandle->plugin->context);
- if (err) {
- static const char*format = "DispatchOneSignal(Callback) label%s func=%s args=%s";
- if (afb_req_is_valid(request)) afb_req_fail_f(request, "DISPATCH-CTL-MODE:Cb", format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ));
- else AFB_ERROR(format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ));
- return -1;
- }
- break;
-
- default:
- {
- static const char*format = "DispatchOneSignal(unknown) mode control=%s action=%s";
- AFB_ERROR(format, signals[index]->label);
- if (afb_req_is_valid(request))afb_req_fail_f(request, "DISPATCH-CTL-MODE:Unknown", format, signals[index]->label);
- }
- }
- }
-
- // everything when fine
- if (afb_req_is_valid(request)) afb_req_success(request, NULL, signals[index]->label);
- return 0;
-}
-
-// Event name is mapped on control label and executed as a standard control
-/*
-void DispatchOneEvent(const char *evtLabel, json_object *eventJ) {
- DispatchHandleT **events = configHandle->events;
-
- (void) DispatchOneSignal(CTL_SOURCE_EVENT, events, evtLabel, eventJ, NULL_AFBREQ);
-}
-*/
-// Event name is mapped on control label and executed as a standard control
-
-int DispatchSources() {
- if (!configHandle) return 1;
-
- int err = 0;
- DispatchHandleT **sources = configHandle->sources;
- ssize_t i = 0, nSources = sizeof(*sources) / sizeof(DispatchHandleT);
-
- while(i < nSources) {
- const char* sourceLabel = sources[i++]->label;
- err = DispatchOneSignal(CTL_SOURCE_ONLOAD, sources, sourceLabel, NULL, NULL_AFBREQ);
- }
-
- return err;
-}
-
-void ctlapi_dispatch(afb_req request) {
- DispatchHandleT **signals = configHandle->signals;
- json_object *queryJ, *argsJ=NULL;
- const char *target;
- DispatchSourceT source= CTL_SOURCE_UNKNOWN;
-
- queryJ = afb_req_json(request);
- int err = wrap_json_unpack(queryJ, "{s:s, s?i s?o !}", "target", &target, "source", &source, "args", &argsJ);
- if (err) {
- afb_req_fail_f(request, "CTL-DISPTACH-INVALID", "missing target or args not a valid json object query=%s", json_object_get_string(queryJ));
- return;
- }
-
- (void) DispatchOneSignal(source, signals, target, argsJ, request);
-}
-
-// Wrapper to Lua2c plugin command add context dans delegate to LuaWrapper
-int DispatchOneL2c(lua_State* luaState, char *funcname, Lua2cFunctionT callback) {
-#ifndef CONTROL_SUPPORT_LUA
- AFB_ERROR("DISPATCH-ONE-L2C: LUA support not selected (cf:CONTROL_SUPPORT_LUA) in config.cmake");
- return 1;
-#else
- int err=Lua2cWrapper(luaState, funcname, callback, configHandle->plugin->context);
- return err;
-#endif
-}
-
-
-// List Avaliable Configuration Files
-
-void ctlapi_config(struct afb_req request) {
- json_object*tmpJ;
- char *dirList;
- // Compile some default directories to browse
- char defaultConfPath[CONTROL_MAXPATH_LEN];
- strncpy(defaultConfPath, GetBindingDirPath(), sizeof(GetBindingDirPath()));
- strncat(defaultConfPath, "/etc:", sizeof(defaultConfPath) - strlen(defaultConfPath) - 1);
- strncat(defaultConfPath, GetBindingDirPath(), sizeof(defaultConfPath) - strlen(defaultConfPath) - 1);
- strncat(defaultConfPath, "/data", sizeof(defaultConfPath) - strlen(defaultConfPath) - 1);
-
-
- json_object* queryJ = afb_req_json(request);
- if (queryJ && json_object_object_get_ex(queryJ, "cfgpath", &tmpJ)) {
- dirList = strdup(json_object_get_string(tmpJ));
- } else {
-
- dirList = getenv("CONTROL_CONFIG_PATH");
- if (!dirList) dirList = defaultConfPath;
- AFB_NOTICE("CONFIG-MISSING: use default CONTROL_CONFIG_PATH=%s", defaultConfPath);
- }
-
- // get list of config file
- struct json_object *responseJ = ScanForConfig(dirList, CTL_SCAN_RECURSIVE, "onload", "json");
-
- if (json_object_array_length(responseJ) == 0) {
- afb_req_fail(request, "CONFIGPATH:EMPTY", "No Config Found in CONTROL_CONFIG_PATH");
- } else {
- afb_req_success(request, responseJ, NULL);
- }
-
- return;
-}
-
-// unpack individual action object
-
-static int DispatchLoadOneAction(DispatchConfigT *controlConfig, json_object *actionJ, DispatchActionT *action) {
- char *api = NULL, *verb = NULL, *callback = NULL, *lua = NULL, *function = NULL;
- int err, modeCount = 0;
-
- err = wrap_json_unpack(actionJ, "{s?s,s?s,s?s,s?s,s?s,s?s,s?s,s?o !}"
- , "label", &action->label
- , "info", &action->info
- , "function", &function
- , "callback", &callback
- , "lua", &lua
- , "api", &api, "verb", &verb
- , "args", &action->argsJ);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-ACTION Missing something label|info|callback|lua|(api+verb)|args in %s", json_object_get_string(actionJ));
- return -1;
- }
-
- // Generic way to specify a C or LUA actions
- if(function) {
- if(strcasestr(function, "lua")) {
- action->mode = CTL_MODE_LUA;
- action->call = function;
- modeCount++;
- }
- else if(controlConfig->plugin) {
- action->mode = CTL_MODE_CB;
- action->call = callback;
- modeCount++;
-
- action->actionCB = dlsym(controlConfig->plugin->dlHandle, callback);
- if (!action->actionCB) {
- AFB_ERROR("DISPATCH-LOAD-ACTION fail to find calbback=%s in %s", callback, controlConfig->plugin->sharelib);
- return -1;
- }
- }
- // If label not already set then use function name
- if(! &action->label) action->label = function;
- }
-
- if (lua) {
- action->mode = CTL_MODE_LUA;
- action->call = lua;
- modeCount++;
- // If label not already set then use function name
- if(! &action->label) action->label = lua;
- }
-
- if (api && verb) {
- action->mode = CTL_MODE_API;
- action->api = api;
- action->call = verb;
- modeCount++;
- char* apiVerb = strdup(api);
- apiVerb = strncat(apiVerb, "/", sizeof(*apiVerb) - strlen(apiVerb) - 1);
- apiVerb = strncat(apiVerb, verb, sizeof(*apiVerb) - strlen(apiVerb) - 1);
- // If label not already set then use function name
- if(! &action->label) action->label = apiVerb;
- free(apiVerb);
- }
-
- if (callback && controlConfig->plugin) {
- action->mode = CTL_MODE_CB;
- action->call = callback;
- modeCount++;
-
- action->actionCB = dlsym(controlConfig->plugin->dlHandle, callback);
- if (!action->actionCB) {
- AFB_ERROR("DISPATCH-LOAD-ACTION fail to find calbback=%s in %s", callback, controlConfig->plugin->sharelib);
- return -1;
- }
- }
-
- // make sure at least one mode is selected
- if (modeCount == 0) {
- AFB_ERROR("DISPATCH-LOAD-ACTION No Action Selected lua|callback|(api+verb) in %s", json_object_get_string(actionJ));
- return -1;
- }
-
- if (modeCount > 1) {
- AFB_ERROR("DISPATCH-LOAD-ACTION:Too Many arguments lua|callback|(api+verb) in %s", json_object_get_string(actionJ));
- return -1;
- }
- return 0;
-};
-
-static DispatchActionT *DispatchLoadActions(DispatchConfigT *controlConfig, json_object *actionsJ) {
- int err;
- DispatchActionT *actions;
-
- // action array is close with a nullvalue;
- if (json_object_get_type(actionsJ) == json_type_array) {
- int count = json_object_array_length(actionsJ);
- actions = calloc(count + 1, sizeof (DispatchActionT));
-
- for (int idx = 0; idx < count; idx++) {
- json_object *actionJ = json_object_array_get_idx(actionsJ, idx);
- err = DispatchLoadOneAction(controlConfig, actionJ, &actions[idx]);
- if (err) return NULL;
- }
-
- } else {
- actions = calloc(2, sizeof (DispatchActionT));
- err = DispatchLoadOneAction(controlConfig, actionsJ, &actions[0]);
- if (err) return NULL;
- }
-
- return actions;
-}
-
-static void DispatchLoadPlugin(DispatchConfigT *controlConfig, json_object* sourcesJ, json_object* pluginJ)
-{
- int err = 0;
- json_object *lua2csJ = NULL;
- DispatchPluginT *dPlugin= calloc(1, sizeof(DispatchPluginT));
- controlConfig->plugin = dPlugin;
- const char*ldSearchPath=NULL;
-
- err = wrap_json_unpack(pluginJ, "{ss,s?s,s?s,ss,s?o!}",
- "label", &dPlugin->label, "info", &dPlugin->info, "ldpath", &ldSearchPath, "sharelib", &dPlugin->sharelib, "lua2c", &lua2csJ);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:ONLOAD Plugin missing label|[info]|sharelib|[lua2c] in %s", json_object_get_string(sourcesJ));
- return;
- }
-
- // if search path not in Json config file, then try default
- if (!ldSearchPath) ldSearchPath= strncat(GetBindingDirPath(), "/data", sizeof(GetBindingDirPath()) - strlen(GetBindingDirPath()) - 1);
-
- // search for default policy config file
- json_object *pluginPathJ = ScanForConfig(ldSearchPath, CTL_SCAN_RECURSIVE, dPlugin->sharelib, NULL);
- if (!pluginPathJ || json_object_array_length(pluginPathJ) == 0) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:PLUGIN Missing plugin=%s in path=%s", dPlugin->sharelib, ldSearchPath);
- return;
- }
-
- char *filename;
- char*fullpath;
- err = wrap_json_unpack(json_object_array_get_idx(pluginPathJ, 0), "{s:s, s:s !}", "fullpath", &fullpath, "filename", &filename);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:PLUGIN HOOPs invalid plugin file path = %s", json_object_get_string(pluginPathJ));
- return;
- }
-
- if (json_object_array_length(pluginPathJ) > 1) {
- AFB_WARNING("DISPATCH-LOAD-CONFIG:PLUGIN plugin multiple instances in searchpath will use %s/%s", fullpath, filename);
- }
-
- char pluginpath[CONTROL_MAXPATH_LEN];
- strncpy(pluginpath, fullpath, sizeof (pluginpath));
- strncat(pluginpath, "/", sizeof (pluginpath)-strlen(pluginpath)-1);
- strncat(pluginpath, filename, sizeof (pluginpath)-strlen(pluginpath)-1);
- dPlugin->dlHandle = dlopen(pluginpath, RTLD_NOW);
- if (!dPlugin->dlHandle) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:PLUGIN Fail to load pluginpath=%s err= %s", pluginpath, dlerror());
- return;
- }
-
- CtlPluginMagicT *ctlPluginMagic = (CtlPluginMagicT*) dlsym(dPlugin->dlHandle, "CtlPluginMagic");
- if (!ctlPluginMagic || ctlPluginMagic->magic != CTL_PLUGIN_MAGIC) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:Plugin symbol'CtlPluginMagic' missing or != CTL_PLUGIN_MAGIC plugin=%s", pluginpath);
- return;
- } else {
- AFB_NOTICE("DISPATCH-LOAD-CONFIG:Plugin %s successfully registered", ctlPluginMagic->label);
- }
-
- // Jose hack to make verbosity visible from sharelib
- struct afb_binding_data_v2 *afbHidenData = dlsym(dPlugin->dlHandle, "afbBindingV2data");
- if (afbHidenData) *afbHidenData = afbBindingV2data;
-
- // Push lua2cWrapper @ into plugin
- Lua2cWrapperT *lua2cInPlug = dlsym(dPlugin->dlHandle, "Lua2cWrap");
-#ifndef CONTROL_SUPPORT_LUA
- if (lua2cInPlug) *lua2cInPlug = NULL;
-#else
- // Lua2cWrapper is part of binder and not expose to dynamic link
- if (lua2cInPlug) *lua2cInPlug = DispatchOneL2c;
-
- {
- int Lua2cAddOne(luaL_Reg *l2cFunc, const char* l2cName, int index) {
- char funcName[CONTROL_MAXPATH_LEN];
- strncpy(funcName, "lua2c_", sizeof(funcName));
- strncat(funcName, l2cName, sizeof(funcName)-strlen(funcName)-1);
-
- Lua2cFunctionT l2cFunction= (Lua2cFunctionT)dlsym(dPlugin->dlHandle, funcName);
- if (!l2cFunction) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:Plugin symbol'%s' missing err=%s", funcName, dlerror());
- return 1;
- }
- l2cFunc[index].func=(void*)l2cFunction;
- l2cFunc[index].name=strdup(l2cName);
-
- return 0;
- }
-
- int errCount = 0;
- luaL_Reg *l2cFunc=NULL;
- int count=0;
-
- // look on l2c command and push them to LUA
- if (json_object_get_type(lua2csJ) == json_type_array) {
- int length = json_object_array_length(lua2csJ);
- l2cFunc = calloc(length + 1, sizeof (luaL_Reg));
- for (count=0; count < length; count++) {
- int err;
- const char *l2cName = json_object_get_string(json_object_array_get_idx(lua2csJ, count));
- err = Lua2cAddOne(l2cFunc, l2cName, count);
- if (err) errCount++;
- }
- } else {
- l2cFunc = calloc(2, sizeof (luaL_Reg));
- const char *l2cName = json_object_get_string(lua2csJ);
- errCount = Lua2cAddOne(l2cFunc, l2cName, 0);
- count=1;
- }
- if (errCount) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:Plugin %d symbols not found in plugin='%s'", errCount, pluginpath);
- return;
- } else {
- dPlugin->l2cFunc= l2cFunc;
- dPlugin->l2cCount= count;
- }
- }
-#endif
- DispatchPluginInstallCbT ctlPluginOnload = dlsym(dPlugin->dlHandle, "CtlPluginOnload");
- if (ctlPluginOnload) {
- dPlugin->context = (*ctlPluginOnload) (controlConfig->label, controlConfig->version, controlConfig->info);
- }
-}
-
-static DispatchHandleT *DispatchLoadSignal(DispatchConfigT *controlConfig, json_object *controlJ) {
- json_object *actionsJ, *permissionsJ;
- int err;
-
- DispatchHandleT *dispatchHandle = calloc(1, sizeof (DispatchHandleT));
- err = wrap_json_unpack(controlJ, "{ss,s?s,ss,ss,s?o,so !}"
- , "id", &dispatchHandle->label
- , "info", &dispatchHandle->info
- , "source", &dispatchHandle->ssource
- , "class", &dispatchHandle->sclass
- , "permissions", &permissionsJ
- , "onReceived", &actionsJ);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:CONTROL Missing something label|[info]|actions in %s", json_object_get_string(controlJ));
- return NULL;
- }
-
- dispatchHandle->actions = DispatchLoadActions(controlConfig, actionsJ);
- if (!dispatchHandle->actions) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:CONTROL Error when parsing actions %s", dispatchHandle->label);
- return NULL;
- }
- return dispatchHandle;
-}
-
-static DispatchHandleT *DispatchLoadSource(DispatchConfigT *controlConfig, json_object *sourcesJ) {
- json_object *actionsJ = NULL, *pluginJ = NULL;
- int err;
-
- DispatchHandleT *dispatchSources = calloc(1, sizeof (DispatchHandleT));
- err = wrap_json_unpack(sourcesJ, "{ss,s?s,s?o,s?o,s?o !}",
- "api", &dispatchSources->label, "info", &dispatchSources->info, "plugin", &pluginJ, "actions", &actionsJ);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:ONLOAD Missing something label|[info]|[plugin]|[actions] in %s", json_object_get_string(sourcesJ));
- return NULL;
- }
-
- // best effort to initialise everything before starting
- err = afb_daemon_require_api(dispatchSources->label, 1);
- if (err) {
- AFB_WARNING("DISPATCH-LOAD-CONFIG:REQUIRE Fail to get=%s", dispatchSources->label);
- }
-
- if (pluginJ) {
- DispatchLoadPlugin(controlConfig, sourcesJ, pluginJ);
- }
-
- dispatchSources->actions = DispatchLoadActions(controlConfig, actionsJ);
- if (!dispatchSources->actions) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:ONLOAD Error when parsing actions %s", dispatchSources->label);
- return NULL;
- }
- return dispatchSources;
-}
-
-static DispatchConfigT *DispatchLoadConfig(const char* filepath) {
- json_object *controlConfigJ, *ignoreJ;
- int err;
-
- // Load JSON file
- controlConfigJ = json_object_from_file(filepath);
- if (!controlConfigJ) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:JsonLoad invalid JSON %s ", filepath);
- return NULL;
- }
-
- AFB_INFO("DISPATCH-LOAD-CONFIG: loading config filepath=%s", filepath);
-
- json_object *metadataJ = NULL, *sourcesJ = NULL, *signalsJ = NULL;
- err = wrap_json_unpack(controlConfigJ, "{s?s,s?o,s?o,s?o !}", "$schema", &ignoreJ, "metadata", &metadataJ, "sources", &sourcesJ, "signals", &signalsJ);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG Missing something metadata|[sources]|[signals] in %s", json_object_get_string(controlConfigJ));
- return NULL;
- }
-
- DispatchConfigT *controlConfig = calloc(1, sizeof (DispatchConfigT));
- if (metadataJ) {
- const char*ctlname=NULL;
- err = wrap_json_unpack(metadataJ, "{ss,s?s,s?s,ss !}", "label", &controlConfig->label, "version", &controlConfig->version, "name", &ctlname, "info", &controlConfig->info);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:METADATA Missing something label|version|[label] in %s", json_object_get_string(metadataJ));
- return NULL;
- }
-
- // if ctlname is provided change process name now
- if (ctlname) {
- err= prctl(PR_SET_NAME, ctlname,NULL,NULL,NULL);
- if (err) AFB_WARNING("Fail to set Process Name to:%s",ctlname);
- }
- }
-
- if (sourcesJ) {
- DispatchHandleT *dispatchHandle;
-
- if (json_object_get_type(sourcesJ) != json_type_array) {
- controlConfig->sources = (DispatchHandleT**) calloc(2, sizeof (void*));
- dispatchHandle = DispatchLoadSource(controlConfig, sourcesJ);
- controlConfig->sources[0] = dispatchHandle;
- } else {
- int length = json_object_array_length(sourcesJ);
- controlConfig->sources = (DispatchHandleT**) calloc(length + 1, sizeof (void*));
-
- for (int jdx = 0; jdx < length; jdx++) {
- json_object *sourcesJ = json_object_array_get_idx(sourcesJ, jdx);
- dispatchHandle = DispatchLoadSource(controlConfig, sourcesJ);
- controlConfig->sources[jdx] = dispatchHandle;
- }
- }
- }
-
- if (signalsJ) {
- DispatchHandleT* dispatchHandle;
-
- if (json_object_get_type(signalsJ) != json_type_array) {
- controlConfig->signals = (DispatchHandleT**) calloc(2, sizeof (void*));
- dispatchHandle = DispatchLoadSignal(controlConfig, signalsJ);
- controlConfig->signals[0] = dispatchHandle;
- } else {
- int length = json_object_array_length(signalsJ);
- controlConfig->signals = (DispatchHandleT**) calloc(length + 1, sizeof (void*));
-
- for (int jdx = 0; jdx < length; jdx++) {
- json_object *controlJ = json_object_array_get_idx(signalsJ, jdx);
- dispatchHandle = DispatchLoadSignal(controlConfig, controlJ);
- controlConfig->signals[jdx] = dispatchHandle;
- }
- }
- }
-/*
- if (eventsJ) {
- DispatchHandleT *dispatchHandle;
-
- if (json_object_get_type(eventsJ) != json_type_array) {
- controlConfig->events = (DispatchHandleT**) calloc(2, sizeof (void*));
- dispatchHandle = DispatchLoadSignal(controlConfig, eventsJ);
- controlConfig->events[0] = dispatchHandle;
- } else {
- int length = json_object_array_length(eventsJ);
- controlConfig->events = (DispatchHandleT**) calloc(length + 1, sizeof (void*));
-
- for (int jdx = 0; jdx < length; jdx++) {
- json_object *eventJ = json_object_array_get_idx(eventsJ, jdx);
- dispatchHandle = DispatchLoadSignal(controlConfig, eventJ);
- controlConfig->events[jdx] = dispatchHandle;
- }
- }
- }
-*/
- return controlConfig;
-}
-
-
-// Load default config file at init
-
-int DispatchInit() {
- int index, luaLoaded = 0;
- char controlFile [CONTROL_MAXPATH_LEN];
- // Compile some default directories to browse
- char defaultConfPath[CONTROL_MAXPATH_LEN];
- strncpy(defaultConfPath, GetBindingDirPath(), sizeof(GetBindingDirPath()));
- strncat(defaultConfPath, "/etc:", sizeof(defaultConfPath) - strlen(defaultConfPath) - 1);
- strncat(defaultConfPath, GetBindingDirPath(), sizeof(defaultConfPath) - strlen(defaultConfPath) - 1);
- strncat(defaultConfPath, "/data", sizeof(defaultConfPath) - strlen(defaultConfPath) - 1);
-
- const char *dirList = getenv("CONTROL_CONFIG_PATH");
- if (!dirList) dirList = defaultConfPath;
-
- strncpy(controlFile, CONTROL_CONFIG_PRE "-", CONTROL_MAXPATH_LEN);
- strncat(controlFile, GetBinderName(), CONTROL_MAXPATH_LEN-strlen(controlFile)-1);
-
- // search for default dispatch config file
- json_object* responseJ = ScanForConfig(dirList, CTL_SCAN_RECURSIVE, controlFile, "json");
-
- // We load 1st file others are just warnings
- for (index = 0; index < json_object_array_length(responseJ); index++) {
- json_object *entryJ = json_object_array_get_idx(responseJ, index);
-
- char *filename;
- char*fullpath;
- int err = wrap_json_unpack(entryJ, "{s:s, s:s !}", "fullpath", &fullpath, "filename", &filename);
- if (err) {
- AFB_ERROR("DISPATCH-INIT HOOPs invalid JSON entry= %s", json_object_get_string(entryJ));
- return -1;
- }
-
- if (index == 0) {
- if (strcasestr(filename, controlFile)) {
- char filepath[CONTROL_MAXPATH_LEN];
- strncpy(filepath, fullpath, sizeof (filepath));
- strncat(filepath, "/", sizeof (filepath)-strlen(filepath)-1);
- strncat(filepath, filename, sizeof (filepath)-strlen(filepath)-1);
- configHandle = DispatchLoadConfig(filepath);
- if (!configHandle) {
- AFB_ERROR("DISPATCH-INIT:ERROR Fail loading [%s]", filepath);
- return -1;
- }
- luaLoaded = 1;
- break;
- }
- } else {
- AFB_WARNING("DISPATCH-INIT:WARNING Secondary Signal Config Ignored %s/%s", fullpath, filename);
- }
- }
-
- // no dispatch config found remove control API from binder
- if (!luaLoaded) {
- AFB_WARNING("DISPATCH-INIT:WARNING (setenv CONTROL_CONFIG_PATH) No Config '%s-*.json' in '%s'", controlFile, dirList);
- }
-
- AFB_NOTICE("DISPATCH-INIT:SUCCES: Signal Dispatch Init");
- return 0;
-}