aboutsummaryrefslogtreecommitdiffstats
path: root/controller
diff options
context:
space:
mode:
authorRomain Forlot <romain.forlot@iot.bzh>2017-12-04 17:21:14 +0100
committerRomain Forlot <romain.forlot@iot.bzh>2017-12-14 11:00:49 +0100
commitd4ed9b98b766ee2f5b44278cc00fbec21cd36b41 (patch)
treeaa6795b42aca0f3bb5cb4e69e6a42b9129676833 /controller
parent181851ec87ec913d1727177b3a17438871732827 (diff)
Remove old controller submodule
Change-Id: I8768bc2663884b8043ad9565e8cbb62c4ba78070 Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
Diffstat (limited to 'controller')
-rw-r--r--controller/CMakeLists.txt43
-rw-r--r--controller/ctl-action.c180
-rw-r--r--controller/ctl-config.c225
-rw-r--r--controller/ctl-config.h120
-rw-r--r--controller/ctl-lua.c1080
-rw-r--r--controller/ctl-lua.h90
-rw-r--r--controller/ctl-onload.c57
-rw-r--r--controller/ctl-plugin.c248
-rw-r--r--controller/ctl-plugin.h84
-rw-r--r--controller/ctl-timer.c101
-rw-r--r--controller/ctl-timer.h42
11 files changed, 0 insertions, 2270 deletions
diff --git a/controller/CMakeLists.txt b/controller/CMakeLists.txt
deleted file mode 100644
index 5269bcc..0000000
--- a/controller/CMakeLists.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-###########################################################################
-# Copyright 2015, 2016, 2017 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, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-###########################################################################
-
-# Include LUA only when requested
-get_property(COMPDEF DIRECTORY PROPERTY COMPILE_DEFINITIONS)
-if("CONTROL_SUPPORT_LUA=1" IN_LIST COMPDEF)
- message(STATUS "Notice: LUA Controler Support Selected")
- set(CTL_LUA_SOURCE ctl-lua.c ctl-timer.c)
- ADD_COMPILE_OPTIONS(-DCONTROL_SUPPORT_LUA)
-else()
- message(STATUS "Warning: LUA Without Support ")
-endif()
-
-# Add target to project dependency list
-PROJECT_TARGET_ADD(afb-controller)
-
- # Define project Targets
- ADD_LIBRARY(${TARGET_NAME} STATIC ctl-action.c ctl-config.c ctl-onload.c ctl-plugin.c ${CTL_LUA_SOURCE})
-
- # Library dependencies (include updates automatically)
- TARGET_LINK_LIBRARIES(${TARGET_NAME}
- ${link_libraries}
- )
-
- # Define target includes for this target client
- TARGET_INCLUDE_DIRECTORIES(${TARGET_NAME}
- PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
- )
diff --git a/controller/ctl-action.c b/controller/ctl-action.c
deleted file mode 100644
index ff618d6..0000000
--- a/controller/ctl-action.c
+++ /dev/null
@@ -1,180 +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 "ctl-config.h"
-#ifdef CONTROL_SUPPORT_LUA
-#include "ctl-lua.h"
-#endif
-
-int ActionExecOne(CtlActionT* action, json_object *queryJ) {
- int err;
-
- switch (action->type) {
- case CTL_TYPE_API:
- {
- json_object *returnJ;
-
- // if query is empty increment usage count and pass args else
- // create new JSON object
- if (!queryJ || json_object_get_type(queryJ) != json_type_object) {
- if(action->argsJ) {
- json_object_get(action->argsJ);
- queryJ = action->argsJ;
- }
- else {
- queryJ = json_object_new_object();
- }
- } else if (action->argsJ) {
-
- // Merge queryJ and argsJ before sending request
- if (json_object_get_type(action->argsJ) == json_type_object) {
-
- json_object_object_foreach(action->argsJ, key, val) {
- json_object_object_add(queryJ, key, val);
- }
- } else {
- json_object_object_add(queryJ, "args", action->argsJ);
- }
- }
- json_object_object_add(queryJ, "label", json_object_new_string(action->source.label));
-
- int err = afb_service_call_sync(action->api, action->call, queryJ, &returnJ);
- if (err) {
- static const char*format = "ActionExecOne(Api) api=%s verb=%s args=%s";
- AFB_ERROR(format, action->api, action->call, action->source.label);
- goto OnErrorExit;
- }
- break;
- }
-
-#ifdef CONTROL_SUPPORT_LUA
- case CTL_TYPE_LUA:
- err = LuaCallFunc(action, queryJ);
- if (err) {
- AFB_ERROR("ActionExecOne(Lua) label=%s func=%s args=%s", action->source.label, action->call, json_object_get_string(action->argsJ));
- goto OnErrorExit;
- }
- break;
-#endif
-
- case CTL_TYPE_CB:
- err = (*action->actionCB) (&action->source, action->argsJ, queryJ);
- if (err) {
- AFB_ERROR("ActionExecOne(Callback) label%s func=%s args=%s", action->source.label, action->call, json_object_get_string(action->argsJ));
- goto OnErrorExit;
- }
- break;
-
- default:
- {
- AFB_ERROR("ActionExecOne(unknown) API type label=%s", action->source.label);
- goto OnErrorExit;
- }
- }
-
- return 0;
-
-OnErrorExit:
- return -1;
-}
-
-
-// unpack individual action object
-
-int ActionLoadOne(CtlActionT *action, json_object *actionJ) {
- char *api = NULL, *verb = NULL, *lua = NULL;
- int err, modeCount = 0;
- json_object *callbackJ=NULL;
-
- err = wrap_json_unpack(actionJ, "{ss,s?s,s?o,s?s,s?s,s?s,s?o !}"
- , "label", &action->source.label, "info", &action->source.info, "callback", &callbackJ, "lua", &lua, "api", &api, "verb", &verb, "args", &action->argsJ);
- if (err) {
- AFB_ERROR("ACTION-LOAD-ONE Missing something label|info|callback|lua|(api+verb)|args in:\n-- %s", json_object_get_string(actionJ));
- goto OnErrorExit;
- }
-
- if (lua) {
- action->type = CTL_TYPE_LUA;
- action->call = lua;
- modeCount++;
- }
-
- if (api && verb) {
- action->type = CTL_TYPE_API;
- action->api = api;
- action->call = verb;
- modeCount++;
- }
-
- if (callbackJ) {
- action->type = CTL_TYPE_CB;
- modeCount++;
- err = PluginGetCB (action, callbackJ);
- if (err) goto OnErrorExit;
-
- }
-
- // make sure at least one mode is selected
- if (modeCount == 0) {
- AFB_ERROR("ACTION-LOAD-ONE No Action Selected lua|callback|(api+verb) in %s", json_object_get_string(actionJ));
- goto OnErrorExit;
- }
-
- if (modeCount > 1) {
- AFB_ERROR("ACTION-LOAD-ONE:ToMany arguments lua|callback|(api+verb) in %s", json_object_get_string(actionJ));
- goto OnErrorExit;
- }
- return 0;
-
-OnErrorExit:
- return 1;
-};
-
-CtlActionT *ActionLoad(json_object *actionsJ) {
- int err = 0;
- CtlActionT *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 (CtlActionT));
-
- for (int idx = 0; idx < count; idx++) {
- json_object *actionJ = json_object_array_get_idx(actionsJ, idx);
- err = ActionLoadOne(&actions[idx], actionJ);
- if (err) goto OnErrorExit;
- }
-
- } else {
- actions = calloc(2, sizeof (CtlActionT));
- err = ActionLoadOne(&actions[0], actionsJ);
- if (err) goto OnErrorExit;
- }
-
- return actions;
-
-OnErrorExit:
- return NULL;
-
-}
diff --git a/controller/ctl-config.c b/controller/ctl-config.c
deleted file mode 100644
index cf24057..0000000
--- a/controller/ctl-config.c
+++ /dev/null
@@ -1,225 +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 "filescan-utils.h"
-#include "ctl-config.h"
-
-// Load control config file
-
-char* CtlConfigSearch(const char *dirList, const char* fileName) {
- int index;
- char controlFile [CONTROL_MAXPATH_LEN];
-
- if(fileName) {
- strncpy(controlFile, fileName, CONTROL_MAXPATH_LEN);
- } else {
- strncpy(controlFile, CONTROL_CONFIG_PRE "-", CONTROL_MAXPATH_LEN);
- strncat(controlFile, GetBinderName(), strlen(GetBinderName())); // Only possible because returned GetBinderName value is a static variable.
- }
-
- // 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("CTL-INIT HOOPs invalid JSON entry= %s", json_object_get_string(entryJ));
- return NULL;
- }
-
- if (index == 0) {
- if (strcasestr(filename, controlFile)) {
- char filepath[CONTROL_MAXPATH_LEN];
- strncpy(filepath, fullpath, strlen(fullpath));
- strncat(filepath, "/", strlen("/"));
- strncat(filepath, filename, strlen(filename));
- return (strdup(filepath));
- }
- }
- }
-
- // no config found
- return NULL;
-}
-
-json_object* loadJSON(const char* filepath, const char* fileName)
-{
- // Search for config in filepath
- const char* filepathFound = CtlConfigSearch(filepath, fileName);
- if(!filepathFound)
- {
- AFB_ERROR("CTL-LOAD-CONFIG No JSON Config found in %s", filepath);
- return NULL;
- }
- return json_object_from_file(filepathFound);
-}
-
-int browseAdditionnalFiles(CtlConfigT* ctlConfig, const char* filepath, int sectionIdx){
- int err = 0;
- int done = 0;
- const char* fileName;
- json_object* configJ = NULL, *sectionJ = NULL;
- CtlSectionT* sections = ctlConfig->sections;
-
- if (json_object_get_type(ctlConfig->filesJ) == json_type_array) {
- int filesEnd = json_object_array_length(ctlConfig->filesJ);
- for (int jdx = 0; jdx < filesEnd; jdx++) {
- fileName = json_object_get_string(json_object_array_get_idx(ctlConfig->filesJ, jdx));
- configJ = loadJSON(filepath, fileName);
- if(json_object_object_get_ex(configJ, sections[sectionIdx].key, &sectionJ))
- {
- err += sections[sectionIdx].loadCB(&sections[sectionIdx], sectionJ);
- done++;
- }
- }
- if(!done) {
- AFB_ERROR("CtlConfigLoad: fail to find '%s' section in config '%s' with '%s' in its name", sections[sectionIdx].key, filepath, fileName);
- err++;
- }
- if(err) {goto OnErrorExit;}
- } else {
- fileName = json_object_get_string(ctlConfig->filesJ);
- configJ = loadJSON(filepath, fileName);
- if(json_object_object_get_ex(configJ, sections[sectionIdx].key, &sectionJ)) {
- err += sections[sectionIdx].loadCB(&sections[sectionIdx], sectionJ);
- done++;
- }
- else {
- AFB_ERROR("CtlConfigLoad: fail to find '%s' section in config '%s' with '%s' in its name", sections[sectionIdx].key, filepath, fileName);
- err++;
- }
- if(err) {goto OnErrorExit;}
- }
-
- return err;
-
- OnErrorExit:
- return err;
-}
-
-int CtlConfigExec(CtlConfigT *ctlConfig) {
- // best effort to initialise everything before starting
- if (ctlConfig->requireJ) {
-
- void DispatchRequireOneApi(json_object * bindindJ) {
- const char* requireBinding = json_object_get_string(bindindJ);
- int err = afb_daemon_require_api(requireBinding, 1);
- if (err) {
- AFB_WARNING("CTL-LOAD-CONFIG:REQUIRE Fail to get=%s", requireBinding);
- }
- }
-
- if (json_object_get_type(ctlConfig->requireJ) == json_type_array) {
- for (int idx = 0; idx < json_object_array_length(ctlConfig->requireJ); idx++) {
- DispatchRequireOneApi(json_object_array_get_idx(ctlConfig->requireJ, idx));
- }
- } else {
- DispatchRequireOneApi(ctlConfig->requireJ);
- }
- }
-
-#ifdef CONTROL_SUPPORT_LUA
- int err= LuaConfigExec();
- if (err) goto OnErrorExit;
-#endif
-
- // Loop on every section and process config
- int errcount=0;
- for (int idx = 0; ctlConfig->sections[idx].key != NULL; idx++) {
- errcount += ctlConfig->sections[idx].loadCB(&ctlConfig->sections[idx], NULL);
- }
- return errcount;
-
- OnErrorExit:
- return 1;
-}
-
-CtlConfigT *CtlConfigLoad(const char* filepath, CtlSectionT *sections) {
- json_object *ctlConfigJ;
- CtlConfigT *ctlConfig = calloc(1, sizeof (CtlConfigT));
- int err;
-
-#ifdef CONTROL_SUPPORT_LUA
- err = LuaConfigLoad();
- if (err) goto OnErrorExit;
-#endif
-
- // Load JSON file
- ctlConfigJ = loadJSON(filepath, NULL);
- if (!ctlConfigJ) {
- AFB_ERROR("CTL-LOAD-CONFIG Invalid JSON %s ", filepath);
- goto OnErrorExit;
- }
-
- AFB_INFO("CTL-LOAD-CONFIG: loading config filepath=%s", filepath);
-
- json_object *metadataJ;
- int done = json_object_object_get_ex(ctlConfigJ, "metadata", &metadataJ);
- if (done) {
- err = wrap_json_unpack(metadataJ, "{ss,ss,ss,s?s,s?o,s?o !}",
- "label", &ctlConfig->label,
- "version", &ctlConfig->version,
- "api", &ctlConfig->api,
- "info", &ctlConfig->info,
- "require", &ctlConfig->requireJ,
- "files",&ctlConfig->filesJ);
- if (err) {
- AFB_ERROR("CTL-LOAD-CONFIG:METADATA Missing something label|api|version|[info]|[require] in:\n-- %s", json_object_get_string(metadataJ));
- goto OnErrorExit;
- }
-
- // Should replace this with API name change
- if (ctlConfig->api) {
- err = afb_daemon_rename_api(ctlConfig->api);
- if (err) AFB_WARNING("Fail to rename api to:%s", ctlConfig->api);
- }
- }
-
- //load config sections
- err = 0;
- ctlConfig->sections = sections;
-
- for (int idx = 0; sections[idx].key != NULL; idx++) {
- json_object * sectionJ = NULL;
- int done = json_object_object_get_ex(ctlConfigJ, sections[idx].key, &sectionJ);
- if (!done) {
- AFB_DEBUG("CtlConfigLoad: fail to find '%s' section in config '%s'. Searching deeper", sections[idx].key, filepath);
- err += browseAdditionnalFiles(ctlConfig, filepath, idx);
- } else {
- err += sections[idx].loadCB(&sections[idx], sectionJ);
- }
- }
- if (err) goto OnErrorExit;
-
- return (ctlConfig);
-
-OnErrorExit:
- free(ctlConfig);
- return NULL;
-}
diff --git a/controller/ctl-config.h b/controller/ctl-config.h
deleted file mode 100644
index 25a066c..0000000
--- a/controller/ctl-config.h
+++ /dev/null
@@ -1,120 +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
- */
-
-#ifndef _CTL_CONFIG_INCLUDE_
-#define _CTL_CONFIG_INCLUDE_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#define AFB_BINDING_VERSION 2
-#include <afb/afb-binding.h>
-#include <json-c/json.h>
-#include <filescan-utils.h>
-#include <wrap-json.h>
-
-#include "ctl-plugin.h"
-
-#ifndef CONTROL_MAXPATH_LEN
- #define CONTROL_MAXPATH_LEN 255
-#endif
-
-#ifndef CONTROL_CONFIG_PRE
- #define CONTROL_CONFIG_PRE "init"
-#endif
-
-#ifndef CTL_PLUGIN_EXT
- #define CTL_PLUGIN_EXT ".ctlso"
-#endif
-
-typedef enum {
- CTL_TYPE_NONE=0,
- CTL_TYPE_API,
- CTL_TYPE_CB,
- CTL_TYPE_LUA,
-} CtlActionTypeT;
-
-typedef struct {
- CtlActionTypeT type;
- const char* api;
- const char* call;
- json_object *argsJ;
- int (*actionCB)(CtlSourceT *source, json_object *argsJ, json_object *queryJ);
- CtlSourceT source;
-} CtlActionT;
-
-typedef struct {
- const char* label;
- const char *info;
- CtlActionT *actions;
-} DispatchHandleT;
-
-typedef struct ConfigSectionS {
- const char *key;
- const char *label;
- const char *info;
- int (*loadCB)(struct ConfigSectionS *section, json_object *sectionJ);
- void *handle;
-} CtlSectionT;
-
-typedef struct {
- const char* api;
- const char* label;
- const char *info;
- const char *version;
- json_object *requireJ;
- json_object *filesJ;
- CtlSectionT *sections;
-} CtlConfigT;
-
-#ifdef CONTROL_SUPPORT_LUA
- #include "ctl-lua.h"
-#else
- typedef struct lua_State lua_State;
- typedef void *Lua2cFunctionT;
- typedef void* Lua2cWrapperT;
-#endif
-
-// ctl-action.c
-CtlActionT *ActionLoad(json_object *actionsJ);
-int ActionExecOne(CtlActionT* action, json_object *queryJ);
-int ActionLoadOne(CtlActionT *action, json_object *actionJ);
-
-// ctl-config.c
-CtlConfigT *CtlConfigLoad(const char* filepath, CtlSectionT *sections);
-int CtlConfigExec(CtlConfigT *ctlConfig);
-
-// ctl-onload.c
-int OnloadConfig(CtlSectionT *section, json_object *actionsJ);
-
-// ctl-plugin.c
-int PluginConfig(CtlSectionT *section, json_object *pluginsJ);
-int PluginGetCB (CtlActionT *action , json_object *callbackJ);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CTL_CONFIG_INCLUDE_ */
diff --git a/controller/ctl-lua.c b/controller/ctl-lua.c
deleted file mode 100644
index 76faed6..0000000
--- a/controller/ctl-lua.c
+++ /dev/null
@@ -1,1080 +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, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ref:
- * (manual) https://www.lua.org/manual/5.3/manual.html
- * (lua->C) http://www.troubleshooters.com/codecorn/lua/lua_c_calls_lua.htm#_Anatomy_of_a_Lua_Call
- * (lua/C Var) http://acamara.es/blog/2012/08/passing-variables-from-lua-5-2-to-c-and-vice-versa/
- * (Lua/C Lib)https://john.nachtimwald.com/2014/07/12/wrapping-a-c-library-in-lua/
- * (Lua/C Table) https://gist.github.com/SONIC3D/10388137
- * (Lua/C Nested table) https://stackoverflow.com/questions/45699144/lua-nested-table-from-lua-to-c
- * (Lua/C Wrapper) https://stackoverflow.com/questions/45699950/lua-passing-handle-to-function-created-with-newlib
- *
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-
-#include "ctl-config.h"
-
-#define LUA_FIST_ARG 2 // when using luaL_newlib calllback receive libtable as 1st arg
-#define LUA_MSG_MAX_LENGTH 512
-#define JSON_ERROR (json_object*)-1
-static afb_req NULL_AFBREQ = {};
-
-
-static lua_State* luaState;
-
-#define CTX_MAGIC 123456789
-#define CTX_TOKEN "AFB_ctx"
-
-typedef struct {
- char *name;
- int count;
- afb_event event;
-} LuaAfbEvent;
-static LuaAfbEvent *luaDefaultEvt;
-
-typedef struct {
- int ctxMagic;
- afb_req request;
- void *handle;
- char *info;
-} LuaAfbContextT;
-
-typedef struct {
- const char *callback;
- json_object *context;
- void *handle;
-} LuaCallServiceT;
-
-typedef enum {
- AFB_MSG_INFO,
- AFB_MSG_WARNING,
- AFB_MSG_NOTICE,
- AFB_MSG_DEBUG,
- AFB_MSG_ERROR,
-} LuaAfbMessageT;
-
-/*
- * Note(Fulup): I fail to use luaL_setmetatable and replaced it with a simple opaque
- * handle while waiting for someone smarter than me to find a better solution
- * https://stackoverflow.com/questions/45596493/lua-using-lua-newuserdata-from-lua-pcall
- */
-
-STATIC LuaAfbContextT *LuaCtxCheck (lua_State *luaState, int index) {
- LuaAfbContextT *afbContext;
- //luaL_checktype(luaState, index, LUA_TUSERDATA);
- //afbContext = (LuaAfbContextT *)luaL_checkudata(luaState, index, CTX_TOKEN);
- luaL_checktype(luaState, index, LUA_TLIGHTUSERDATA);
- afbContext = (LuaAfbContextT *) lua_touserdata(luaState, index);
- if (afbContext == NULL && afbContext->ctxMagic != CTX_MAGIC) {
- luaL_error(luaState, "Fail to retrieve user data context=%s", CTX_TOKEN);
- AFB_ERROR ("afbContextCheck error retrieving afbContext");
- return NULL;
- }
- return afbContext;
-}
-
-STATIC LuaAfbContextT *LuaCtxPush (lua_State *luaState, afb_req request, void *handle, const char* info) {
- // LuaAfbContextT *afbContext = (LuaAfbContextT *)lua_newuserdata(luaState, sizeof(LuaAfbContextT));
- // luaL_setmetatable(luaState, CTX_TOKEN);
- LuaAfbContextT *afbContext = (LuaAfbContextT *)calloc(1, sizeof(LuaAfbContextT));
- lua_pushlightuserdata(luaState, afbContext);
- if (!afbContext) {
- AFB_ERROR ("LuaCtxPush fail to allocate user data context");
- return NULL;
- }
- afbContext->ctxMagic=CTX_MAGIC;
- afbContext->info=strdup(info);
- afbContext->request= request;
- afbContext->handle= handle;
- return afbContext;
-}
-
-STATIC void LuaCtxFree (LuaAfbContextT *afbContext) {
- free(afbContext->info);
- free(afbContext);
-}
-
-// Push a json structure on the stack as a LUA table
-STATIC int LuaPushArgument (json_object *argsJ) {
-
- //AFB_NOTICE("LuaPushArgument argsJ=%s", json_object_get_string(argsJ));
-
- json_type jtype= json_object_get_type(argsJ);
- switch (jtype) {
- case json_type_object: {
- lua_newtable (luaState);
- json_object_object_foreach (argsJ, key, val) {
- int done = LuaPushArgument (val);
- if (done) {
- lua_setfield(luaState,-2, key);
- }
- }
- break;
- }
- case json_type_array: {
- int length= json_object_array_length(argsJ);
- lua_newtable (luaState);
- for (int idx=0; idx < length; idx ++) {
- json_object *val=json_object_array_get_idx(argsJ, idx);
- LuaPushArgument (val);
- lua_seti (luaState,-2, idx);
- }
- break;
- }
- case json_type_int:
- lua_pushinteger(luaState, json_object_get_int(argsJ));
- break;
- case json_type_string:
- lua_pushstring(luaState, json_object_get_string(argsJ));
- break;
- case json_type_boolean:
- lua_pushboolean(luaState, json_object_get_boolean(argsJ));
- break;
- case json_type_double:
- lua_pushnumber(luaState, json_object_get_double(argsJ));
- break;
- case json_type_null:
- AFB_WARNING("LuaPushArgument: NULL object type %s", json_object_get_string(argsJ));
- return 0;
- break;
-
- default:
- AFB_ERROR("LuaPushArgument: unsupported Json object type %s", json_object_get_string(argsJ));
- return 0;
- }
- return 1;
-}
-
-STATIC json_object *LuaPopOneArg (lua_State* luaState, int idx);
-
-// Move a table from Internal Lua representation to Json one
-// Numeric table are transformed in json array, string one in object
-// Mix numeric/string key are not supported
-STATIC json_object *LuaTableToJson (lua_State* luaState, int index) {
- #define LUA_KEY_INDEX -2
- #define LUA_VALUE_INDEX -1
-
- int idx;
- int tableType;
- json_object *tableJ= NULL;
-
- lua_pushnil(luaState); // 1st key
- if (index < 0) index--;
- for (idx=1; lua_next(luaState, index) != 0; idx++) {
-
- // uses 'key' (at index -2) and 'value' (at index -1)
- if (lua_type(luaState,LUA_KEY_INDEX) == LUA_TSTRING) {
-
- if (!tableJ) {
- tableJ= json_object_new_object();
- tableType=LUA_TSTRING;
- } else if (tableType != LUA_TSTRING){
- AFB_ERROR("MIX Lua Table with key string/numeric not supported");
- return NULL;
- }
-
- const char *key= lua_tostring(luaState, LUA_KEY_INDEX);
- json_object *argJ= LuaPopOneArg(luaState, LUA_VALUE_INDEX);
- json_object_object_add(tableJ, key, argJ);
-
- } else {
- if (!tableJ) {
- tableJ= json_object_new_array();
- tableType=LUA_TNUMBER;
- } else if(tableType != LUA_TNUMBER) {
- AFB_ERROR("MIX Lua Table with key numeric/string not supported");
- return NULL;
- }
-
- json_object *argJ= LuaPopOneArg(luaState, LUA_VALUE_INDEX);
- json_object_array_add(tableJ, argJ);
- }
-
-
- lua_pop(luaState, 1); // removes 'value'; keeps 'key' for next iteration
- }
-
- // Query is empty free empty json object
- if (idx == 1) {
- json_object_put(tableJ);
- return NULL;
- }
- return tableJ;
-}
-
-STATIC json_object *LuaPopOneArg (lua_State* luaState, int idx) {
- json_object *value=NULL;
-
- int luaType = lua_type(luaState, idx);
- switch(luaType) {
- case LUA_TNUMBER: {
- lua_Number number= lua_tonumber(luaState, idx);;
- int nombre = (int)number; // evil trick to determine wether n fits in an integer. (stolen from ltcl.c)
- if (number == nombre) {
- value= json_object_new_int((int)number);
- } else {
- value= json_object_new_double(number);
- }
- break;
- }
- case LUA_TBOOLEAN:
- value= json_object_new_boolean(lua_toboolean(luaState, idx));
- break;
- case LUA_TSTRING:
- value= json_object_new_string(lua_tostring(luaState, idx));
- break;
- case LUA_TTABLE:
- value= LuaTableToJson(luaState, idx);
- break;
- case LUA_TNIL:
- value=json_object_new_string("nil") ;
- break;
- case LUA_TUSERDATA:
- value=json_object_new_int64((int64_t)lua_touserdata(luaState, idx)); // store userdata as int !!!
- break;
-
- default:
- AFB_NOTICE ("LuaPopOneArg: script returned Unknown/Unsupported idx=%d type:%d/%s", idx, luaType, lua_typename(luaState, luaType));
- value=NULL;
- }
-
- return value;
-}
-
-static json_object *LuaPopArgs (lua_State* luaState, int start) {
- json_object *responseJ;
-
- int stop = lua_gettop(luaState);
- if(stop-start <0) return NULL;
-
- // start at 2 because we are using a function array lib
- if (start == stop) {
- responseJ=LuaPopOneArg (luaState, start);
- } else {
- // loop on remaining return arguments
- responseJ= json_object_new_array();
- for (int idx=start; idx <= stop; idx++) {
- json_object *argJ=LuaPopOneArg (luaState, idx);
- if (!argJ) goto OnErrorExit;
- json_object_array_add(responseJ, argJ);
- }
- }
-
- return responseJ;
-
- OnErrorExit:
- return NULL;
-}
-
-STATIC int LuaFormatMessage(lua_State* luaState, LuaAfbMessageT action) {
- char *message;
-
- json_object *responseJ= LuaPopArgs(luaState, LUA_FIST_ARG);
-
- if (!responseJ) {
- luaL_error(luaState,"LuaFormatMessage empty message");
- goto OnErrorExit;
- }
-
- // if we have only on argument just return the value.
- if (json_object_get_type(responseJ)!=json_type_array || json_object_array_length(responseJ) <2) {
- message= (char*)json_object_get_string(responseJ);
- goto PrintMessage;
- }
-
- // extract format and push all other parameter on the stack
- message = alloca (LUA_MSG_MAX_LENGTH);
- const char *format = json_object_get_string(json_object_array_get_idx(responseJ, 0));
-
- int arrayIdx=1;
- int targetIdx=0;
-
- for (int idx=0; format[idx] !='\0'; idx++) {
-
- if (format[idx]=='%' && format[idx] !='\0') {
- json_object *slotJ= json_object_array_get_idx(responseJ, arrayIdx);
- //if (slotJ) AFB_NOTICE("**** idx=%d slotJ=%s", arrayIdx, json_object_get_string(slotJ));
-
-
- switch (format[++idx]) {
- case 'd':
- if (slotJ) targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"%d", json_object_get_int(slotJ));
- else targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"nil");
- arrayIdx++;
- break;
- case 'f':
- if (slotJ) targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"%f", json_object_get_double(slotJ));
- else targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"nil");
- arrayIdx++;
- break;
-
- case'%':
- message[targetIdx]='%';
- targetIdx++;
- break;
-
- case 's':
- default:
- if (slotJ) targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"%s", json_object_get_string(slotJ));
- else targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"nil");
- arrayIdx++;
- }
-
- } else {
- if (targetIdx >= LUA_MSG_MAX_LENGTH) {
- AFB_WARNING ("LuaFormatMessage: message[%s] owerverflow LUA_MSG_MAX_LENGTH=%d", format, LUA_MSG_MAX_LENGTH);
- targetIdx --; // move backward for EOL
- break;
- } else {
- message[targetIdx++] = format[idx];
- }
- }
- }
- message[targetIdx]='\0';
-
-PrintMessage:
- switch (action) {
- case AFB_MSG_WARNING:
- AFB_WARNING ("%s", message);
- break;
- case AFB_MSG_NOTICE:
- AFB_NOTICE ("%s", message);
- break;
- case AFB_MSG_DEBUG:
- AFB_DEBUG ("%s", message);
- break;
- case AFB_MSG_INFO:
- AFB_INFO ("%s", message);
- break;
- case AFB_MSG_ERROR:
- default:
- AFB_ERROR ("%s", message);
- }
- return 0; // nothing return to lua
-
- OnErrorExit: // on argument to return (the error message)
- return 1;
-}
-
-STATIC int LuaPrintInfo(lua_State* luaState) {
- int err=LuaFormatMessage (luaState, AFB_MSG_INFO);
- return err;
-}
-
-STATIC int LuaPrintError(lua_State* luaState) {
- int err=LuaFormatMessage (luaState, AFB_MSG_ERROR);
- return err; // no value return
-}
-
-STATIC int LuaPrintWarning(lua_State* luaState) {
- int err=LuaFormatMessage (luaState, AFB_MSG_WARNING);
- return err;
-}
-
-STATIC int LuaPrintNotice(lua_State* luaState) {
- int err=LuaFormatMessage (luaState, AFB_MSG_NOTICE);
- return err;
-}
-
-STATIC int LuaPrintDebug(lua_State* luaState) {
- int err=LuaFormatMessage (luaState, AFB_MSG_DEBUG);
- return err;
-}
-
-STATIC int LuaAfbSuccess(lua_State* luaState) {
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIST_ARG);
- if (!afbContext) goto OnErrorExit;
-
- // ignore context argument
- json_object *responseJ= LuaPopArgs(luaState, LUA_FIST_ARG+1);
- if (responseJ == JSON_ERROR) return 1;
-
- afb_req_success(afbContext->request, responseJ, NULL);
-
- LuaCtxFree(afbContext);
- return 0;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbFail(lua_State* luaState) {
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIST_ARG);
- if (!afbContext) goto OnErrorExit;
-
- json_object *responseJ= LuaPopArgs(luaState, LUA_FIST_ARG+1);
- if (responseJ == JSON_ERROR) return 1;
-
- afb_req_fail(afbContext->request, afbContext->info, json_object_get_string(responseJ));
-
- LuaCtxFree(afbContext);
- return 0;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC void LuaAfbServiceCB(void *handle, int iserror, struct json_object *responseJ) {
- LuaCallServiceT *contextCB= (LuaCallServiceT*)handle;
- int count=1;
-
- lua_getglobal(luaState, contextCB->callback);
-
- // push error status & response
- lua_pushboolean(luaState, iserror);
- count+= LuaPushArgument(responseJ);
- count+= LuaPushArgument(contextCB->context);
-
- int err=lua_pcall(luaState, count, LUA_MULTRET, 0);
- if (err) {
- AFB_ERROR ("LUA-SERICE-CB:FAIL response=%s err=%s", json_object_get_string(responseJ), lua_tostring(luaState,-1) );
- }
-
- free (contextCB);
-}
-
-
-STATIC int LuaAfbService(lua_State* luaState) {
- int count = lua_gettop(luaState);
-
- // note: argument start at 2 because of AFB: table
- if (count <5 || !lua_isstring(luaState, 2) || !lua_isstring(luaState, 3) || !lua_istable(luaState, 4) || !lua_isstring(luaState, 5)) {
- lua_pushliteral (luaState, "ERROR: syntax AFB:service(api, verb, {[Lua Table]})");
- goto OnErrorExit;
- }
-
- // get api/verb+query
- const char *api = lua_tostring(luaState,2);
- const char *verb= lua_tostring(luaState,3);
- json_object *queryJ= LuaTableToJson(luaState, 4);
- if (queryJ == JSON_ERROR) return 1;
-
- LuaCallServiceT *contextCB = calloc (1, sizeof(LuaCallServiceT));
- contextCB->callback= lua_tostring(luaState, 5);
- contextCB->context = LuaPopArgs(luaState, 6);
-
- afb_service_call(api, verb, queryJ, LuaAfbServiceCB, contextCB);
-
- return 0; // no value return
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbServiceSync(lua_State* luaState) {
- int count = lua_gettop(luaState);
- json_object *responseJ;
-
- // note: argument start at 2 because of AFB: table
- if (count <3 || !lua_isstring(luaState, 2) || !lua_isstring(luaState, 3) || !lua_istable(luaState, 4)) {
- lua_pushliteral (luaState, "ERROR: syntax AFB:servsync(api, verb, {[Lua Table]})");
- goto OnErrorExit;
- }
-
- // get api/verb+query
- const char *api = lua_tostring(luaState,2);
- const char *verb= lua_tostring(luaState,3);
- json_object *queryJ= LuaTableToJson(luaState, 4);
-
- int iserror=afb_service_call_sync (api, verb, queryJ, &responseJ);
-
- // push error status & response
- count=1; lua_pushboolean(luaState, iserror);
- count+= LuaPushArgument(responseJ);
-
- return count; // return count values
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbEventPush(lua_State* luaState) {
- LuaAfbEvent *afbevt;
- int index;
-
- // if no private event handle then use default binding event
- if (lua_islightuserdata(luaState, LUA_FIST_ARG)) {
- afbevt = (LuaAfbEvent*) lua_touserdata(luaState, LUA_FIST_ARG);
- index=LUA_FIST_ARG+1;
- } else {
- index=LUA_FIST_ARG;
- afbevt=luaDefaultEvt;
- }
-
- if (!afb_event_is_valid(afbevt->event)) {
- lua_pushliteral (luaState, "LuaAfbMakePush-Fail invalid event");
- goto OnErrorExit;
- }
-
- json_object *ctlEventJ= LuaTableToJson(luaState, index);
- if (!ctlEventJ) {
- lua_pushliteral (luaState, "LuaAfbEventPush-Syntax is AFB:signal ([evtHandle], {lua table})");
- goto OnErrorExit;
- }
-
- int done = afb_event_push(afbevt->event, ctlEventJ);
- if (!done) {
- lua_pushliteral (luaState, "LuaAfbEventPush-Fail No Subscriber to event");
- AFB_ERROR ("LuaAfbEventPush-Fail name subscriber event=%s count=%d", afbevt->name, afbevt->count);
- goto OnErrorExit;
- }
- afbevt->count++;
- return 0;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbEventSubscribe(lua_State* luaState) {
- LuaAfbEvent *afbevt;
-
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIST_ARG);
- if (!afbContext) {
- lua_pushliteral (luaState, "LuaAfbEventSubscribe-Fail Invalid request handle");
- goto OnErrorExit;
- }
-
- // if no private event handle then use default binding event
- if (lua_islightuserdata(luaState, LUA_FIST_ARG+1)) {
- afbevt = (LuaAfbEvent*) lua_touserdata(luaState, LUA_FIST_ARG+1);
- } else {
- afbevt=luaDefaultEvt;
- }
-
- if (!afb_event_is_valid(afbevt->event)) {
- lua_pushliteral (luaState, "LuaAfbMakePush-Fail invalid event handle");
- goto OnErrorExit;
- }
-
- int err = afb_req_subscribe(afbContext->request, afbevt->event);
- if (err) {
- lua_pushliteral (luaState, "LuaAfbEventSubscribe-Fail No Subscriber to event");
- AFB_ERROR ("LuaAfbEventPush-Fail name subscriber event=%s count=%d", afbevt->name, afbevt->count);
- goto OnErrorExit;
- }
- afbevt->count++;
- return 0;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbEventMake(lua_State* luaState) {
- int count = lua_gettop(luaState);
- LuaAfbEvent *afbevt=calloc(1,sizeof(LuaAfbEvent));
-
- if (count != LUA_FIST_ARG || !lua_isstring(luaState, LUA_FIST_ARG)) {
- lua_pushliteral (luaState, "LuaAfbEventMake-Syntax is evtHandle= AFB:event ('myEventName')");
- goto OnErrorExit;
- }
-
- // event name should be the only argument
- afbevt->name= strdup (lua_tostring(luaState,LUA_FIST_ARG));
-
- // create a new binder event
- afbevt->event = afb_daemon_make_event(afbevt->name);
- if (!afb_event_is_valid(afbevt->event)) {
- lua_pushliteral (luaState, "LuaAfbEventMake-Fail to Create Binder event");
- goto OnErrorExit;
- }
-
- // push event handler as a LUA opaque handle
- lua_pushlightuserdata(luaState, afbevt);
- return 1;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-// Function call from LUA when lua2c plugin L2C is used
-int Lua2cWrapper(lua_State* luaState, const char *funcname, Lua2cFunctionT callback) {
-
- json_object *argsJ = LuaPopArgs(luaState, LUA_FIST_ARG);
- int response = (*callback) (funcname, argsJ);
-
- // push response to LUA
- lua_pushinteger(luaState, response);
-
- return 1;
-}
-
-// Call a Lua function from a control action
-int LuaCallFunc (CtlActionT *action, json_object *queryJ) {
-
- int err, count;
-
- json_object* argsJ = action->argsJ;
- const char* func = action->call;
-
- // load function (should exist in CONTROL_PATH_LUA
- lua_getglobal(luaState, func);
-
- // push source on the stack
- count=1;
- lua_pushstring(luaState, action->source.label);
-
- // push argsJ on the stack
- if (!argsJ) {
- lua_pushnil(luaState);
- count++;
- } else {
- count+= LuaPushArgument (argsJ);
- }
-
- // push queryJ on the stack
- if (!queryJ) {
- lua_pushnil(luaState);
- count++;
- } else {
- count+= LuaPushArgument (queryJ);
- }
-
- // effectively exec LUA script code
- err=lua_pcall(luaState, count, 1, 0);
- if (err) {
- AFB_ERROR("LuaCallFunc Fail calling %s error=%s", func, lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
-
- // return LUA script value
- int rc= (int)lua_tointeger(luaState, -1);
- return rc;
-
- OnErrorExit:
- return -1;
-}
-
-
-// Execute LUA code from received API request
-STATIC void LuaDoAction (LuaDoActionT action, afb_req request) {
-
- int err, count=0;
-
- json_object* queryJ = afb_req_json(request);
-
- switch (action) {
-
- case LUA_DOSTRING: {
- const char *script = json_object_get_string(queryJ);
- err=luaL_loadstring(luaState, script);
- if (err) {
- AFB_ERROR ("LUA-DO-COMPILE:FAIL String=%s err=%s", script, lua_tostring(luaState,-1) );
- goto OnErrorExit;
- }
- // Push AFB client context on the stack
- LuaAfbContextT *afbContext= LuaCtxPush(luaState, request,NULL,script);
- if (!afbContext) goto OnErrorExit;
-
- break;
- }
-
- case LUA_DOCALL: {
- const char *func;
- json_object *argsJ=NULL;
-
- err= wrap_json_unpack (queryJ, "{s:s, s?o !}", "target", &func, "args", &argsJ);
- if (err) {
- AFB_ERROR ("LUA-DOCALL-SYNTAX missing target|args query=%s", json_object_get_string(queryJ));
- goto OnErrorExit;
- }
-
- // load function (should exist in CONTROL_PATH_LUA
- lua_getglobal(luaState, func);
-
- // Push AFB client context on the stack
- LuaAfbContextT *afbContext= LuaCtxPush(luaState, request, NULL, func);
- if (!afbContext) goto OnErrorExit;
-
- // push query on the stack
- if (!argsJ) {
- lua_pushnil(luaState);
- count++;
- } else {
- count+= LuaPushArgument (argsJ);
- }
-
- break;
- }
-
- case LUA_DOSCRIPT: { // Fulup need to fix argument passing
- char *filename; char*fullpath;
- char luaScriptPath[CONTROL_MAXPATH_LEN];
- int index;
-
- // scan luascript search path once
- static json_object *luaScriptPathJ =NULL;
-
- // extract value from query
- const char *target=NULL,*func=NULL;
- json_object *argsJ=NULL;
- err= wrap_json_unpack (queryJ, "{s:s,s?s,s?s,s?o !}","target", &target,"path",&luaScriptPathJ,"function",&func,"args",&argsJ);
- if (err) {
- AFB_ERROR ("LUA-DOSCRIPT-SYNTAX:missing target|[path]|[function]|[args] query=%s", json_object_get_string(queryJ));
- goto OnErrorExit;
- }
-
- // search for filename=script in binding data dir
- if (!luaScriptPathJ) {
- const char* dirList = strncat(GetBindingDirPath(), "/data", sizeof(GetBindingDirPath()) - strlen(GetBindingDirPath()) - 1);
- strncpy(luaScriptPath,CONTROL_DOSCRIPT_PRE, sizeof(luaScriptPath));
- strncat(luaScriptPath,"-", strlen("-"));
- strncat(luaScriptPath,target, strlen(target));
- luaScriptPathJ= ScanForConfig(dirList, CTL_SCAN_RECURSIVE,luaScriptPath,".lua");
- }
- for (index=0; index < json_object_array_length(luaScriptPathJ); index++) {
- json_object *entryJ=json_object_array_get_idx(luaScriptPathJ, index);
-
- err= wrap_json_unpack (entryJ, "{s:s, s:s !}", "fullpath", &fullpath,"filename", &filename);
- if (err) {
- AFB_ERROR ("LUA-DOSCRIPT-SCAN:HOOPs invalid config file path = %s", json_object_get_string(entryJ));
- goto OnErrorExit;
- }
-
- if (index > 0) AFB_WARNING("LUA-DOSCRIPT-SCAN:Ignore second script=%s path=%s", filename, fullpath);
- else {
- strncpy (luaScriptPath, fullpath, sizeof(luaScriptPath));
- strncat (luaScriptPath, "/", sizeof(luaScriptPath));
- strncat (luaScriptPath, filename, strlen(filename));
- }
- }
-
- err= luaL_loadfile(luaState, luaScriptPath);
- if (err) {
- AFB_ERROR ("LUA-DOSCRIPT HOOPs Error in LUA loading scripts=%s err=%s", luaScriptPath, lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
-
- // script was loaded we need to parse to make it executable
- err=lua_pcall(luaState, 0, 0, 0);
- if (err) {
- AFB_ERROR ("LUA-DOSCRIPT:FAIL to load %s", luaScriptPath);
- goto OnErrorExit;
- }
-
- // if no func name given try to deduct from filename
- if (!func && (func=(char*)GetMidleName(filename))!=NULL) {
- strncpy(luaScriptPath,"_", sizeof(luaScriptPath));
- strncat(luaScriptPath,func, strlen(func));
- func=luaScriptPath;
- }
- if (!func) {
- AFB_ERROR ("LUA-DOSCRIPT:FAIL to deduct funcname from %s", filename);
- goto OnErrorExit;
- }
-
- // load function (should exist in CONTROL_PATH_LUA
- lua_getglobal(luaState, func);
-
- // Push AFB client context on the stack
- LuaAfbContextT *afbContext= LuaCtxPush(luaState, request, NULL, func);
- if (!afbContext) goto OnErrorExit;
-
- // push function arguments
- if (!argsJ) {
- lua_pushnil(luaState);
- count++;
- } else {
- count+= LuaPushArgument(argsJ);
- }
-
- break;
- }
-
- default:
- AFB_ERROR ("LUA-DOSCRIPT-ACTION unknown query=%s", json_object_get_string(queryJ));
- goto OnErrorExit;
- }
-
- // effectively exec LUA code (afb_reply/fail done later from callback)
- err=lua_pcall(luaState, count+1, 0, 0);
- if (err) {
- AFB_ERROR ("LUA-DO-EXEC:FAIL query=%s err=%s", json_object_get_string(queryJ), lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
- return;
-
- OnErrorExit:
- afb_req_fail(request,"LUA:ERROR", lua_tostring(luaState,-1));
- return;
-}
-
-void ctlapi_execlua (afb_req request) {
- LuaDoAction (LUA_DOSTRING, request);
-}
-
-void ctlapi_request (afb_req request) {
- LuaDoAction (LUA_DOCALL, request);
-}
-
-void ctlapi_debuglua (afb_req request) {
- LuaDoAction (LUA_DOSCRIPT, request);
-}
-
-STATIC int LuaTimerClear (lua_State* luaState) {
-
- // Get Timer Handle
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIST_ARG);
- if (!afbContext) goto OnErrorExit;
-
- // retrieve useful information opaque handle
- TimerHandleT *timerHandle = (TimerHandleT*)afbContext->handle;
-
- AFB_NOTICE ("LuaTimerClear timer=%s", timerHandle->label);
- TimerEvtStop(timerHandle);
-
- return 0; //happy end
-
-OnErrorExit:
- return 1;
-}
-STATIC int LuaTimerGet (lua_State* luaState) {
-
- // Get Timer Handle
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIST_ARG);
- if (!afbContext) goto OnErrorExit;
-
- // retrieve useful information opaque handle
- TimerHandleT *timerHandle = (TimerHandleT*)afbContext->handle;
-
- // create response as a JSON object
- json_object *responseJ= json_object_new_object();
- json_object_object_add(responseJ,"label", json_object_new_string(timerHandle->label));
- json_object_object_add(responseJ,"delay", json_object_new_int(timerHandle->delay));
- json_object_object_add(responseJ,"count", json_object_new_int(timerHandle->count));
-
- // return JSON object as Lua table
- int count=LuaPushArgument(responseJ);
-
- // free json object
- json_object_put(responseJ);
-
- return count; // return argument
-
-OnErrorExit:
- return 0;
-}
-
-// Timer Callback
-
-// Set timer
-STATIC int LuaTimerSetCB (void *handle) {
- LuaCallServiceT *contextCB =(LuaCallServiceT*) handle;
- TimerHandleT *timerHandle = (TimerHandleT*) contextCB->handle;
- int count;
-
- // push timer handle and user context on Lua stack
- lua_getglobal(luaState, contextCB->callback);
-
- // Push timer handle
- LuaAfbContextT *afbContext= LuaCtxPush(luaState, NULL_AFBREQ, contextCB->handle, timerHandle->label);
- if (!afbContext) goto OnErrorExit;
- count=1;
-
- // Push user Context
- count+= LuaPushArgument(contextCB->context);
-
- int err=lua_pcall(luaState, count, LUA_MULTRET, 0);
- if (err) {
- AFB_ERROR ("LUA-TIMER-CB:FAIL response=%s err=%s", json_object_get_string(contextCB->context), lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
-
- // get return parameter
- if (!lua_isboolean(luaState, -1)) {
- return (lua_toboolean(luaState, -1));
- }
-
- // timer last run free context resource
- if (timerHandle->count == 1) {
- LuaCtxFree(afbContext);
- }
- return 0; // By default we are happy
-
- OnErrorExit:
- return 1; // stop timer
-}
-
-STATIC int LuaTimerSet(lua_State* luaState) {
- const char *label=NULL, *info=NULL;
- int delay=0, count=0;
-
- json_object *timerJ = LuaPopOneArg(luaState, LUA_FIST_ARG);
- const char *callback = lua_tostring(luaState, LUA_FIST_ARG + 1);
- json_object *contextJ = LuaPopOneArg(luaState, LUA_FIST_ARG + 2);
-
- if (lua_gettop(luaState) != LUA_FIST_ARG+2 || !timerJ || !callback || !contextJ) {
- lua_pushliteral(luaState, "LuaTimerSet-Syntax timerset (timerT, 'callback', contextT)");
- goto OnErrorExit;
- }
-
- int err = wrap_json_unpack(timerJ, "{ss, s?s si, si !}", "label", &label, "info", &info, "delay", &delay, "count", &count);
- if (err) {
- lua_pushliteral(luaState, "LuaTimerSet-Syntax timerT={label:xxx delay:ms, count:xx}");
- goto OnErrorExit;
- }
-
- // everything look fine create timer structure
- TimerHandleT *timerHandle = malloc (sizeof (TimerHandleT));
- timerHandle->delay=delay;
- timerHandle->count=count;
- timerHandle->label=label;
-
- // Allocate handle to store context and callback
- LuaCallServiceT *contextCB = calloc (1, sizeof(LuaCallServiceT));
- contextCB->callback= callback;
- contextCB->context = contextJ;
- contextCB->handle = timerHandle;
-
- // fire timer
- TimerEvtStart (timerHandle, LuaTimerSetCB, contextCB);
-
- return 0; // Happy No Return Function
-
-OnErrorExit:
- lua_error(luaState);
- return 1; // return error code
-}
-
-// Register a new L2c list of LUA user plugin commands
-void LuaL2cNewLib(const char *label, luaL_Reg *l2cFunc, int count) {
- // luaL_newlib(luaState, l2cFunc); macro does not work with pointer :(
- luaL_checkversion(luaState);
- lua_createtable(luaState, 0, count+1);
- luaL_setfuncs(luaState, l2cFunc, 0);
- lua_setglobal(luaState, label);
-}
-
-static const luaL_Reg afbFunction[] = {
- {"timerclear", LuaTimerClear},
- {"timerget" , LuaTimerGet},
- {"timerset" , LuaTimerSet},
- {"notice" , LuaPrintNotice},
- {"info" , LuaPrintInfo},
- {"warning" , LuaPrintWarning},
- {"debug" , LuaPrintDebug},
- {"error" , LuaPrintError},
- {"servsync" , LuaAfbServiceSync},
- {"service" , LuaAfbService},
- {"success" , LuaAfbSuccess},
- {"fail" , LuaAfbFail},
- {"subscribe" , LuaAfbEventSubscribe},
- {"evtmake" , LuaAfbEventMake},
- {"evtpush" , LuaAfbEventPush},
-
- {NULL, NULL} /* sentinel */
-};
-
-// Load Lua Interpreter
-int LuaConfigLoad () {
- // open a new LUA interpretor
- luaState = luaL_newstate();
- if (!luaState) {
- AFB_ERROR ("LUA_INIT: Fail to open lua interpretor");
- goto OnErrorExit;
- }
-
- // load auxiliary libraries
- luaL_openlibs(luaState);
-
- // redirect print to AFB_NOTICE
- luaL_newlib(luaState, afbFunction);
- lua_setglobal(luaState, "AFB");
-
- return 0;
-
- OnErrorExit:
- return 1;
-}
-
-// Create Binding Event at Init Exec Time
-int LuaConfigExec () {
-
- int err, index;
- // create default lua event to send test pause/resume
- luaDefaultEvt=calloc(1,sizeof(LuaAfbEvent));
- luaDefaultEvt->name=CONTROL_LUA_EVENT;
- luaDefaultEvt->event = afb_daemon_make_event(CONTROL_LUA_EVENT);
- if (!afb_event_is_valid(luaDefaultEvt->event)) {
- AFB_ERROR ("POLCTL_INIT: Cannot register lua-events=%s ", CONTROL_LUA_EVENT);
- goto OnErrorExit;;
- }
-
- // search for default policy config file
- char fullprefix[CONTROL_MAXPATH_LEN];
- strncpy (fullprefix, CONTROL_CONFIG_PRE "-", sizeof(fullprefix));
- strncat (fullprefix, GetBinderName(), sizeof(fullprefix));
- strncat (fullprefix, "-", sizeof(fullprefix));
-
- const char *dirList = getenv("CONTROL_LUA_PATH");
- if (!dirList) dirList = strncat(GetBindingDirPath(), "/data", sizeof(GetBindingDirPath()) - strlen(GetBindingDirPath()) - 1);
-
- // special case for no lua even when avaliable
- if (!strcasecmp ("/dev/null", dirList)) {
- return 0;
- }
-
- json_object *luaScriptPathJ = ScanForConfig(dirList , CTL_SCAN_RECURSIVE, fullprefix, "lua");
-
- // load+exec any file found in LUA search path
- for (index=0; index < json_object_array_length(luaScriptPathJ); index++) {
- json_object *entryJ=json_object_array_get_idx(luaScriptPathJ, index);
-
- char *filename; char*fullpath;
- err= wrap_json_unpack (entryJ, "{s:s, s:s !}", "fullpath", &fullpath,"filename", &filename);
- if (err) {
- AFB_ERROR ("LUA-INIT HOOPs invalid config file path = %s", json_object_get_string(entryJ));
- goto OnErrorExit;
- }
-
- char filepath[CONTROL_MAXPATH_LEN];
- strncpy(filepath, fullpath, sizeof(filepath));
- strncat(filepath, "/", sizeof(filepath));
- strncat(filepath, filename, strlen(filename));
- err= luaL_loadfile(luaState, filepath);
- if (err) {
- AFB_ERROR ("LUA-LOAD HOOPs Error in LUA loading scripts=%s err=%s", filepath, lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
-
- // exec/compil script
- err = lua_pcall(luaState, 0, 0, 0);
- if (err) {
- AFB_ERROR ("LUA-LOAD HOOPs Error in LUA exec scripts=%s err=%s", filepath, lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
- }
-
- // no policy config found remove control API from binder
- if (index == 0) {
- AFB_WARNING ("POLICY-INIT:WARNING (setenv CONTROL_LUA_PATH) No LUA '%s*.lua' in '%s'", fullprefix, dirList);
- }
-
- AFB_DEBUG("Control-LUA Init Done");
- return 0;
-
- OnErrorExit:
- return 1;
-}
diff --git a/controller/ctl-lua.h b/controller/ctl-lua.h
deleted file mode 100644
index 0b8de45..0000000
--- a/controller/ctl-lua.h
+++ /dev/null
@@ -1,90 +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
- */
-
-#ifndef _LUA_CTL_INCLUDE_
-#define _LUA_CTL_INCLUDE_
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// prefix start debug script
-#ifndef CONTROL_DOSCRIPT_PRE
-#define CONTROL_DOSCRIPT_PRE "debug"
-#endif
-
-// default event name used by LUA
-#ifndef CONTROL_LUA_EVENT
-#define CONTROL_LUA_EVENT "luaevt"
-#endif
-
-#define AFB_BINDING_VERSION 2
-#include <afb/afb-binding.h>
-
-#include <json-c/json.h>
-
-#ifdef SUSE_LUA_INCDIR
-#include <lua5.3/lua.h>
-#include <lua5.3/lauxlib.h>
-#include <lua5.3/lualib.h>
-#else
-#include <lua.h>
-#include <lauxlib.h>
-#include <lualib.h>
-#endif
-
-#include "ctl-timer.h"
-#include "ctl-config.h"
-
-int LuaLibInit ();
-
-typedef int (*Lua2cFunctionT)(const char *funcname, json_object *argsJ);
-typedef int (*Lua2cWrapperT) (lua_State* luaState, const char *funcname, Lua2cFunctionT callback);
-
-#define CTLP_LUALOAD Lua2cWrapperT Lua2cWrap;
-#define CTLP_LUA2C(FuncName, label, argsJ) static int FuncName(const char*label,json_object*argsJ);\
- int lua2c_ ## FuncName(lua_State* luaState){return((*Lua2cWrap)(luaState, MACRO_STR_VALUE(FuncName), FuncName));};\
- static int FuncName(const char* label, json_object* argsJ)
-
-typedef enum {
- LUA_DOCALL,
- LUA_DOSTRING,
- LUA_DOSCRIPT,
-} LuaDoActionT;
-
-int LuaConfigLoad();
-int LuaConfigExec();
-void LuaL2cNewLib(const char *label, luaL_Reg *l2cFunc, int count);
-int Lua2cWrapper(lua_State* luaState, const char *funcname, Lua2cFunctionT callback);
-int LuaCallFunc (CtlActionT *action, json_object *queryJ) ;
-void ctlapi_lua_docall (afb_req request);
-void ctlapi_lua_dostring (afb_req request);
-void ctlapi_lua_doscript (afb_req request);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/controller/ctl-onload.c b/controller/ctl-onload.c
deleted file mode 100644
index 5000542..0000000
--- a/controller/ctl-onload.c
+++ /dev/null
@@ -1,57 +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.
- *
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-
-#include "ctl-config.h"
-
-// onload section receive one action or an array of actions
-int OnloadConfig(CtlSectionT *section, json_object *actionsJ) {
- CtlActionT *actions;
-
- // Load time parse actions in config file
- if (actionsJ != NULL) {
- actions= ActionLoad(actionsJ);
- section->handle=actions;
-
- if (!actions) {
- AFB_ERROR ("OnloadLoad config fail processing onload actions");
- goto OnErrorExit;
- }
-
- } else {
- // Exec time process onload action now
- actions=(CtlActionT*)section->handle;
- if (!actions) {
- AFB_ERROR ("OnloadLoad Cannot Exec Non Existing Onload Action");
- goto OnErrorExit;
- }
-
- for (int idx=0; actions[idx].source.label != NULL; idx ++) {
- ActionExecOne(&actions[idx], NULL);
- }
- }
-
- return 0;
-
-OnErrorExit:
- return 1;
-
-}
diff --git a/controller/ctl-plugin.c b/controller/ctl-plugin.c
deleted file mode 100644
index 62fdb8b..0000000
--- a/controller/ctl-plugin.c
+++ /dev/null
@@ -1,248 +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 <string.h>
-#include <dlfcn.h>
-#include <link.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "ctl-config.h"
-
-static CtlPluginT *ctlPlugins=NULL;
-
-int PluginGetCB (CtlActionT *action , json_object *callbackJ) {
- const char *plugin=NULL, *function=NULL;
- json_object *argsJ;
- int idx;
-
- if (!ctlPlugins) {
- AFB_ERROR ("PluginGetCB plugin section missing cannot call '%s'", json_object_get_string(callbackJ));
- goto OnErrorExit;
- }
-
- int err = wrap_json_unpack(callbackJ, "{ss,ss,s?o!}", "plugin", &plugin, "function", &function, "args", &argsJ);
- if (err) {
- AFB_ERROR("PluginGet missing plugin|function|[args] in %s", json_object_get_string(callbackJ));
- goto OnErrorExit;
- }
-
- for (idx=0; ctlPlugins[idx].label != NULL; idx++) {
- if (!strcasecmp (ctlPlugins[idx].label, plugin)) break;
- }
-
- if (!ctlPlugins[idx].label) {
- AFB_ERROR ("PluginGetCB no plugin with label=%s", plugin);
- goto OnErrorExit;
- }
-
- action->actionCB = dlsym(ctlPlugins[idx].dlHandle, function);
- action->source.context = ctlPlugins[idx].context;
-
- if (!action->actionCB) {
- AFB_ERROR ("PluginGetCB no plugin=%s no function=%s", plugin, function);
- goto OnErrorExit;
- }
- return 0;
-
-OnErrorExit:
- return 1;
-}
-
-// Wrapper to Lua2c plugin command add context and delegate to LuaWrapper
-STATIC int DispatchOneL2c(lua_State* luaState, const char *funcname, Lua2cFunctionT callback) {
-#ifndef CONTROL_SUPPORT_LUA
- AFB_ERROR("CTL-ONE-L2C: LUA support not selected (cf:CONTROL_SUPPORT_LUA) in config.cmake");
- return 1;
-#else
- int err=Lua2cWrapper(luaState, funcname, callback);
- return err;
-#endif
-}
-
-STATIC int PluginLoadOne (CtlPluginT *ctlPlugin, json_object *pluginJ, void* handle) {
- json_object *lua2csJ = NULL, *actionsJ = NULL;
- const char *basename = NULL;
- char *ldSearchPath = NULL;
- void *dlHandle;
-
- // plugin initialises at 1st load further init actions should be place into onload section
- if (!pluginJ) return 0;
-
- int err = wrap_json_unpack(pluginJ, "{ss,s?s,s?s,s?s,ss,s?o,s?o!}",
- "label", &ctlPlugin->label,
- "version", &ctlPlugin->version,
- "info", &ctlPlugin->info,
- "ldpath", &ldSearchPath,
- "basename", &basename,
- "lua2c", &lua2csJ,
- "actions", &actionsJ);
- if (err) {
- AFB_ERROR("CTL-PLUGIN-LOADONE Plugin missing label|basename|version|[info]|[ldpath]|[lua2c]|[actions] in:\n-- %s", json_object_get_string(pluginJ));
- goto OnErrorExit;
- }
-
- // if search path not in Json config file, then try default binding dir
- if (!ldSearchPath) ldSearchPath = getenv("CONTROL_PLUGIN_PATH");
- if (!ldSearchPath) {
- ldSearchPath = strncat(GetBindingDirPath(), "/lib", sizeof(GetBindingDirPath()) - strlen(GetBindingDirPath()) - 1);
- }
-
- // search for default policy config file
- json_object *pluginPathJ = ScanForConfig(ldSearchPath, CTL_SCAN_RECURSIVE, basename, CTL_PLUGIN_EXT);
- if (!pluginPathJ || json_object_array_length(pluginPathJ) == 0) {
- AFB_ERROR("CTL-PLUGIN-LOADONE Missing plugin=%s*%s (config ldpath?) search=\n-- %s", basename, CTL_PLUGIN_EXT, ldSearchPath);
- goto OnErrorExit;
- }
-
- 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("CTL-PLUGIN-LOADONE HOOPs invalid plugin file path=\n-- %s", json_object_get_string(pluginPathJ));
- goto OnErrorExit;
- }
-
- if (json_object_array_length(pluginPathJ) > 1) {
- AFB_WARNING("CTL-PLUGIN-LOADONE plugin multiple instances in searchpath will use %s/%s", fullpath, filename);
- }
-
- char pluginpath[CONTROL_MAXPATH_LEN];
- 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());
- goto OnErrorExit;
- }
-
- CtlPluginMagicT *ctlPluginMagic = (CtlPluginMagicT*) dlsym(dlHandle, "CtlPluginMagic");
- if (!ctlPluginMagic || ctlPluginMagic->magic != CTL_PLUGIN_MAGIC) {
- AFB_ERROR("CTL-PLUGIN-LOADONE symbol'CtlPluginMagic' missing or != CTL_PLUGIN_MAGIC plugin=%s", pluginpath);
- goto OnErrorExit;
- } else {
- AFB_NOTICE("CTL-PLUGIN-LOADONE %s successfully registered", ctlPluginMagic->label);
- }
-
- // store dlopen handle to enable onload action at exec time
- ctlPlugin->dlHandle = dlHandle;
-
- // Push lua2cWrapper @ into plugin
- Lua2cWrapperT *lua2cInPlug = dlsym(dlHandle, "Lua2cWrap");
-#ifndef CONTROL_SUPPORT_LUA
- if (lua2cInPlug) *lua2cInPlug = NULL;
-#else
- // Lua2cWrapper is part of binder and not expose to dynamic link
- if (lua2csJ && 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, strlen(l2cName));
-
- Lua2cFunctionT l2cFunction = (Lua2cFunctionT) dlsym(dlHandle, funcName);
- if (!l2cFunction) {
- AFB_ERROR("CTL-PLUGIN-LOADONE symbol'%s' missing err=%s", funcName, dlerror());
- return 1;
- }
- l2cFunc[index].func = (void*) l2cFunction;
- l2cFunc[index].name = strdup(l2cName);
-
- return 0;
- }
-
- int errCount = 0, count = 0;
- luaL_Reg *l2cFunc = NULL;
-
- // 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("CTL-PLUGIN-LOADONE %d symbols not found in plugin='%s'", errCount, pluginpath);
- goto OnErrorExit;
- }
- else {
- ctlPlugin->l2cFunc = l2cFunc;
- ctlPlugin->l2cCount = count;
- LuaL2cNewLib (ctlPlugin->label,
- ctlPlugin->l2cFunc,
- ctlPlugin->l2cCount);
- }
- }
-#endif
-
-DispatchPluginInstallCbT ctlPluginOnload = dlsym(dlHandle, "CtlPluginOnload");
- if (ctlPluginOnload) {
- ctlPlugin->context = (*ctlPluginOnload) (ctlPlugin, handle);
- }
- return 0;
-
-OnErrorExit:
- return 1;
-}
-
-int PluginConfig(CtlSectionT *section, json_object *pluginsJ) {
- int err=0;
-
- if (ctlPlugins)
- {
- int idx = 0;
- while(ctlPlugins[idx].label != NULL)
- {
- // Jose hack to make verbosity visible from sharedlib and
- // be able to call verb from others api inside the binder
- struct afb_binding_data_v2 *afbHidenData = dlsym(ctlPlugins[idx++].dlHandle, "afbBindingV2data");
- if (afbHidenData) *afbHidenData = afbBindingV2data;
- }
- return 0;
- }
- else
- {
- if (json_object_get_type(pluginsJ) == json_type_array) {
- int length = json_object_array_length(pluginsJ);
- ctlPlugins = calloc (length+1, sizeof(CtlPluginT));
- for (int idx=0; idx < length; idx++) {
- json_object *pluginJ = json_object_array_get_idx(pluginsJ, idx);
- err += PluginLoadOne(&ctlPlugins[idx], pluginJ, section->handle);
- }
- } else {
- ctlPlugins = calloc (2, sizeof(CtlPluginT));
- err += PluginLoadOne(&ctlPlugins[0], pluginsJ, section->handle);
- }
- }
-
- return err;
-}
diff --git a/controller/ctl-plugin.h b/controller/ctl-plugin.h
deleted file mode 100644
index 4b8bd26..0000000
--- a/controller/ctl-plugin.h
+++ /dev/null
@@ -1,84 +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.
- *
- */
-
-
-#ifndef _CTL_PLUGIN_INCLUDE_
-#define _CTL_PLUGIN_INCLUDE_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <json-c/json.h>
-
-#ifndef CTL_PLUGIN_MAGIC
- #define CTL_PLUGIN_MAGIC 852369147
-#endif
-
-#ifndef STATIC
- #define STATIC static
-#endif
-
-#ifndef UNUSED_ARG
- #define UNUSED_ARG(x) UNUSED_ ## x __attribute__((__unused__))
- #define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
-#endif
-
-typedef struct luaL_Reg luaL_Reg;
-
-typedef struct {
- const char *label;
- const char *info;
- afb_req request;
- void *context;
-} CtlSourceT;
-
-typedef struct {
- long magic;
- const char *label;
- void *handle;
-} CtlPluginMagicT;
-
-typedef struct {
- const char *label;
- const char *info;
- const char *version;
- void *context;
- void *dlHandle;
-#ifdef CONTROL_SUPPORT_LUA
- luaL_Reg *l2cFunc;
- int l2cCount;
-#endif
-} CtlPluginT;
-
-typedef void*(*DispatchPluginInstallCbT)(CtlPluginT *plugin, void* handle);
-
-#define MACRO_STR_VALUE(arg) #arg
-#define CTLP_REGISTER(pluglabel) CtlPluginMagicT CtlPluginMagic={.magic=CTL_PLUGIN_MAGIC,.label=pluglabel,.handle=NULL}; struct afb_binding_data_v2;
-#define CTLP_ONLOAD(plugin, handle) void* CtlPluginOnload(CtlPluginT *plugin, void* handle)
-#define CTLP_CAPI(funcname, source, argsJ, queryJ, context) int funcname(CtlSourceT *source, json_object* argsJ, json_object* queryJ, void* context)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CTL_PLUGIN_INCLUDE_ */
diff --git a/controller/ctl-timer.c b/controller/ctl-timer.c
deleted file mode 100644
index 2d99472..0000000
--- a/controller/ctl-timer.c
+++ /dev/null
@@ -1,101 +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, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-#include "ctl-config.h"
-#include "ctl-timer.h"
-
-#define DEFAULT_PAUSE_DELAY 3000
-#define DEFAULT_TEST_COUNT 1
-typedef struct {
- int value;
- const char *label;
-} AutoTestCtxT;
-
-static afb_event afbevt;
-
-STATIC int TimerNext (sd_event_source* source, uint64_t timer, void* handle) {
- TimerHandleT *timerHandle = (TimerHandleT*) handle;
- int done;
- uint64_t usec;
-
- // Rearm timer if needed
- timerHandle->count --;
- if (timerHandle->count == 0) {
- sd_event_source_unref(source);
- free (handle);
- return 0;
- }
- else {
- // otherwise validate timer for a new run
- sd_event_now(afb_daemon_get_event_loop(), CLOCK_MONOTONIC, &usec);
- sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
- sd_event_source_set_time(source, usec + timerHandle->delay*1000);
- }
-
- done= timerHandle->callback(timerHandle->context);
- if (!done) goto OnErrorExit;
-
- return 0;
-
-OnErrorExit:
- AFB_WARNING("TimerNext Callback Fail Tag=%s", timerHandle->label);
- return -1;
-}
-
-void TimerEvtStop(TimerHandleT *timerHandle) {
-
- sd_event_source_unref(timerHandle->evtSource);
- free (timerHandle);
-}
-
-
-void TimerEvtStart(TimerHandleT *timerHandle, timerCallbackT callback, void *context) {
- uint64_t usec;
-
- // populate CB handle
- timerHandle->callback=callback;
- timerHandle->context=context;
-
- // set a timer with ~250us accuracy
- sd_event_now(afb_daemon_get_event_loop(), CLOCK_MONOTONIC, &usec);
- sd_event_add_time(afb_daemon_get_event_loop(), &timerHandle->evtSource, CLOCK_MONOTONIC, usec+timerHandle->delay*1000, 250, TimerNext, timerHandle);
-}
-
-afb_event TimerEvtGet(void) {
- return afbevt;
-}
-
-
-// Create Binding Event at Init
-int TimerEvtInit () {
-
- // create binder event to send test pause/resume
- afbevt = afb_daemon_make_event("control");
- if (!afb_event_is_valid(afbevt)) {
- AFB_ERROR ("POLCTL_INIT: Cannot register ctl-events");
- return 1;
- }
-
- AFB_DEBUG ("Audio Control-Events Init Done");
- return 0;
-}
-
diff --git a/controller/ctl-timer.h b/controller/ctl-timer.h
deleted file mode 100644
index e1a1ef3..0000000
--- a/controller/ctl-timer.h
+++ /dev/null
@@ -1,42 +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, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef CTL_TIMER_INCLUDE
-#define CTL_TIMER_INCLUDE
-
-#include <systemd/sd-event.h>
-
-// ctl-timer.c
-// ----------------------
-typedef int (*timerCallbackT)(void *context);
-
-typedef struct TimerHandleS {
- int count;
- int delay;
- const char*label;
- void *context;
- timerCallbackT callback;
- sd_event_source *evtSource;
-} TimerHandleT;
-
-int TimerEvtInit (void);
-afb_event TimerEvtGet(void);
-void TimerEvtStart(TimerHandleT *timerHandle, timerCallbackT callback, void *context);
-void TimerEvtStop(TimerHandleT *timerHandle);
-
-#endif // CTL_TIMER_INCLUDE