diff options
author | Romain Forlot <romain.forlot@iot.bzh> | 2018-05-14 12:50:39 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@automotivelinux.org> | 2018-05-14 12:50:39 +0000 |
commit | 0ff8c30892be48ecba1265276532f94b242f6289 (patch) | |
tree | 02dcb2b41742d4b00961d64a4552926bb51e2735 | |
parent | 2fa16f981f6e5d86ac5938821e0c533786b60fc7 (diff) | |
parent | 492c6dc1ecba7b8dfd3353a52352645d9f6984e8 (diff) |
Merge changes from topic 'sandbox/claneys/wip'
* changes:
Loads l2c functions per plugin.
Improve json object release
Improve way to loading an action
-rw-r--r-- | ctl-lib/ctl-action.c | 206 | ||||
-rw-r--r-- | ctl-lib/ctl-config.h | 21 | ||||
-rw-r--r-- | ctl-lib/ctl-lua.c | 108 | ||||
-rw-r--r-- | ctl-lib/ctl-lua.h | 2 | ||||
-rw-r--r-- | ctl-lib/ctl-plugin.c | 72 | ||||
-rw-r--r-- | ctl-lib/ctl-plugin.h | 18 |
6 files changed, 214 insertions, 213 deletions
diff --git a/ctl-lib/ctl-action.c b/ctl-lib/ctl-action.c index da2eef1..8459449 100644 --- a/ctl-lib/ctl-action.c +++ b/ctl-lib/ctl-action.c @@ -63,6 +63,7 @@ PUBLIC void ActionExecOne(CtlSourceT *source, CtlActionT* action, json_object *q if(queryJ) { json_object_object_foreach(queryJ, key, val) { + json_object_get(val); json_object_object_add(subcallArgsJ, key, val); } } @@ -97,7 +98,6 @@ PUBLIC void ActionExecOne(CtlSourceT *source, CtlActionT* action, json_object *q if (err) { AFB_ApiError(action->api, "ActionExecOne(Lua) uid=%s func=%s args=%s", source->uid, action->exec.lua.funcname, json_object_get_string(action->argsJ)); } - json_object_put(queryJ); break; #endif @@ -106,16 +106,15 @@ PUBLIC void ActionExecOne(CtlSourceT *source, CtlActionT* action, json_object *q if (err) { AFB_ApiError(action->api, "ActionExecOne(Callback) uid%s plugin=%s function=%s args=%s", source->uid, action->exec.cb.plugin->uid, action->exec.cb.funcname, json_object_get_string(action->argsJ)); } - json_object_put(queryJ); break; default: { AFB_ApiError(action->api, "ActionExecOne(unknown) API type uid=%s", source->uid); - json_object_put(queryJ); break; } } + json_object_put(queryJ); } @@ -137,23 +136,124 @@ STATIC void ActionDynRequest (AFB_ReqT request) { } #endif +/*** This function will fill the CtlActionT pointer given in parameters for a + * given api using an 'uri' that specify the C plugin to use and the name of + * the function + * + */ +static int BuildPluginAction(AFB_ApiT apiHandle, const char *uri, const char *function, CtlActionT *action) +{ + json_object *callbackJ = NULL; + + if(!action) { + AFB_ApiError(apiHandle, "Action not valid"); + return -1; + } + + action->type = CTL_TYPE_CB; + + if(uri && function) { + if(wrap_json_pack(&callbackJ, "{ss,ss,s?o*}", + "plugin", uri, + "function", function, + "args", action->argsJ)) { + AFB_ApiError(apiHandle, "Error packing Callback JSON object for plugin %s and function %s", uri, function); + return -1; + } + else { + return PluginGetCB(apiHandle, action, callbackJ); + } + } + else { + AFB_ApiError(apiHandle, "Miss something uri or function."); + return -1; + } + + return 0; +} + +/*** This function will fill the CtlActionT pointer given in parameters for a + * given api using an 'uri' that specify the API to use and the name of the + * verb + * + * Be aware that 'uri' and 'function' could be null but will result in + * unexpected result. + * + */ +static int BuildApiAction(AFB_ApiT apiHandle, const char *uri, const char *function, CtlActionT *action) +{ + if(!action) { + AFB_ApiError(apiHandle, "Action not valid"); + return -1; + } + + action->type = CTL_TYPE_API; + action->exec.subcall.api = uri; + action->exec.subcall.verb = function; + + return 0; +} + +/*** This function will fill the CtlActionT pointer given in parameters for a + * given api using an 'uri' that specify the Lua plugin to use and the name of + * the function. + * + * Be aware that 'uri' and 'function' could be null but will result in + * unexpected result. + * + */ +#ifdef CONTROL_SUPPORT_LUA +static int BuildLuaAction(AFB_ApiT apiHandle, const char *uri, const char *function, CtlActionT *action) +{ + if(!action) { + AFB_ApiError(apiHandle, "Action not valid"); + return -1; + } + + action->type = CTL_TYPE_LUA; + action->exec.lua.plugin = uri; + action->exec.lua.funcname = function; + + return 0; +} +#endif + +static int BuildOneAction(AFB_ApiT apiHandle, CtlActionT *action, const char *uri, const char *function) { + size_t lua_pre_len = strlen(LUA_ACTION_PREFIX); + size_t api_pre_len = strlen(API_ACTION_PREFIX); + size_t plugin_pre_len = strlen(PLUGIN_ACTION_PREFIX); + + if(uri && function && action) { + if(! strncasecmp(uri, LUA_ACTION_PREFIX, lua_pre_len)) { +#ifdef CONTROL_SUPPORT_LUA + return BuildLuaAction(apiHandle, &uri[lua_pre_len], function, action); +#else + AFB_ApiError(apiHandle, "LUA support not selected at build. Feature disabled"); + return -1; +#endif + } + else if(! strncasecmp(uri, API_ACTION_PREFIX, api_pre_len)) { + return BuildApiAction(apiHandle, &uri[api_pre_len], function, action); + } + else if(! strncasecmp(uri, PLUGIN_ACTION_PREFIX, plugin_pre_len)) { + return BuildPluginAction(apiHandle, &uri[plugin_pre_len], function, action); + } + else { + AFB_ApiError(apiHandle, "Wrong uri specified. You have to specified 'lua://', 'plugin://' or 'api://'. (%s)", function); + return -1; + } + } + + AFB_ApiError(apiHandle, "Uri, Action or function not valid"); + return -1; +} + // unpack individual action object PUBLIC int ActionLoadOne(AFB_ApiT apiHandle, CtlActionT *action, json_object *actionJ, int exportApi) { - int err, modeCount = 0; - json_object *callbackJ=NULL, *luaJ=NULL, *subcallJ=NULL; - - err = wrap_json_unpack(actionJ, "{ss,s?s,s?s,s?o,s?o,s?o,s?o !}", - "uid", &action->uid, - "info", &action->info, - "privileges", &action->privileges, - "callback", &callbackJ, - "lua", &luaJ, - "subcall", &subcallJ, - "args", &action->argsJ); - if (err) { - AFB_ApiError(apiHandle,"ACTION-LOAD-ONE Action missing uid|[info]|[callback]|[lua]|[subcall]|[args] in:\n-- %s", json_object_get_string(actionJ)); - goto OnErrorExit; - } + int err = 0; + const char *uri = NULL, *function = NULL; + + memset(action, 0, sizeof(CtlActionT)); // save per action api handle action->api = apiHandle; @@ -170,67 +270,36 @@ PUBLIC int ActionLoadOne(AFB_ApiT apiHandle, CtlActionT *action, json_object *ac } #endif - if (luaJ) { - modeCount++; - - action->type = CTL_TYPE_LUA; - switch (json_object_get_type(luaJ)) { - case json_type_object: - err = wrap_json_unpack(luaJ, "{s?s,s:s !}", "load", &action->exec.lua.load, "func", &action->exec.lua.funcname); - if (err) { - AFB_ApiError(apiHandle,"ACTION-LOAD-ONE Lua action missing [load]|func in:\n-- %s", json_object_get_string(luaJ)); - goto OnErrorExit; - } - break; - case json_type_string: - action->exec.lua.funcname = json_object_get_string(luaJ); - break; - default: - AFB_ApiError(apiHandle,"ACTION-LOAD-ONE Lua action invalid syntax in:\n-- %s", json_object_get_string(luaJ)); - goto OnErrorExit; + if(actionJ) { + err = wrap_json_unpack(actionJ, "{ss,s?s,ss,ss,s?s,s?o !}", + "uid", &action->uid, + "info", &action->info, + "uri", &uri, + "function", &function, + "privileges", &action->privileges, + "args", &action->argsJ); + if(!err) { + err = BuildOneAction(apiHandle, action, uri, function); } - } - - if (subcallJ) { - modeCount++; - action->type = CTL_TYPE_API; - - err = wrap_json_unpack(subcallJ, "{s?s,s:s !}", "api", &action->exec.subcall.api, "verb", &action->exec.subcall.verb); - if (err) { - AFB_ApiError(apiHandle,"ACTION-LOAD-ONE Subcall missing [load]|func in:\n-- %s", json_object_get_string(subcallJ)); - goto OnErrorExit; + else { + AFB_ApiError(apiHandle, "Wrong action JSON object parameter: (%s)", json_object_to_json_string(actionJ)); + err = -1; } } - - if (callbackJ) { - modeCount++; - action->type = CTL_TYPE_CB; - err = PluginGetCB (apiHandle, action, callbackJ); - if (err) goto OnErrorExit; + else { + AFB_ApiError(apiHandle, "Wrong action JSON object parameter: (%s)", json_object_to_json_string(actionJ)); + err = -1; } - // make sure at least one mode is selected - if (modeCount == 0) { - AFB_ApiError(apiHandle,"ACTION-LOAD-ONE No Action Selected lua|callback|(api+verb) in %s", json_object_get_string(actionJ)); - goto OnErrorExit; - } - - if (modeCount > 1) { - AFB_ApiError(apiHandle,"ACTION-LOAD-ONE:ToMany arguments lua|callback|(api+verb) in %s", json_object_get_string(actionJ)); - goto OnErrorExit; - } - return 0; - -OnErrorExit: - return 1; -}; + return err; +} PUBLIC CtlActionT *ActionConfig(AFB_ApiT apiHandle, json_object *actionsJ, int exportApi) { int err; CtlActionT *actions; // action array is close with a nullvalue; - if (json_object_get_type(actionsJ) == json_type_array) { + if (json_object_is_type(actionsJ, json_type_array)) { size_t count = json_object_array_length(actionsJ); actions = calloc(count + 1, sizeof (CtlActionT)); @@ -251,5 +320,4 @@ PUBLIC CtlActionT *ActionConfig(AFB_ApiT apiHandle, json_object *actionsJ, int e OnErrorExit: return NULL; - } diff --git a/ctl-lib/ctl-config.h b/ctl-lib/ctl-config.h index 432d86c..8a7f2a3 100644 --- a/ctl-lib/ctl-config.h +++ b/ctl-lib/ctl-config.h @@ -33,6 +33,10 @@ extern "C" { #include <filescan-utils.h> #include <wrap-json.h> +#ifdef CONTROL_SUPPORT_LUA + #include "ctl-lua.h" +#endif + #ifndef CONTROL_MAXPATH_LEN #define CONTROL_MAXPATH_LEN 255 #endif @@ -43,8 +47,13 @@ extern "C" { #ifndef CTL_PLUGIN_EXT #define CTL_PLUGIN_EXT ".ctlso" + #define CTL_SCRIPT_EXT ".lua" #endif +#define LUA_ACTION_PREFIX "lua://" +#define API_ACTION_PREFIX "api://" +#define PLUGIN_ACTION_PREFIX "plugin://" + typedef struct ConfigSectionS { const char *key; const char *uid; @@ -64,16 +73,6 @@ typedef struct { CtlSectionT *sections; } CtlConfigT; - -#ifdef CONTROL_SUPPORT_LUA - #include "ctl-lua.h" - - typedef struct CtlLua2cFuncT { - luaL_Reg *l2cFunc; - int l2cCount; -} CtlLua2cFuncT; -#endif - // This should not be global as application may want to define their own sections typedef enum { CTL_SECTION_PLUGIN, @@ -85,7 +84,6 @@ typedef enum { CTL_SECTION_ENDTAG, } SectionEnumT; - // ctl-action.c PUBLIC CtlActionT *ActionConfig(AFB_ApiT apiHandle, json_object *actionsJ, int exportApi); PUBLIC void ActionExecUID(AFB_ReqT request, CtlConfigT *ctlConfig, const char *uid, json_object *queryJ); @@ -93,7 +91,6 @@ PUBLIC void ActionExecOne( CtlSourceT *source, CtlActionT* action, json_object * PUBLIC int ActionLoadOne(AFB_ApiT apiHandle, CtlActionT *action, json_object *, int exportApi); PUBLIC int ActionLabelToIndex(CtlActionT* actions, const char* actionLabel); - // ctl-config.c PUBLIC int CtlConfigMagicNew(); PUBLIC json_object* CtlConfigScan(const char *dirList, const char *prefix) ; diff --git a/ctl-lib/ctl-lua.c b/ctl-lib/ctl-lua.c index d5c2975..89c10b9 100644 --- a/ctl-lib/ctl-lua.c +++ b/ctl-lib/ctl-lua.c @@ -35,9 +35,8 @@ #define LUA_MSG_MAX_LENGTH 512 #define JSON_ERROR (json_object*)-1 - -extern CtlLua2cFuncT *ctlLua2cFunc; static lua_State* luaState; +CtlPluginT *ctlPlugins = NULL; #ifndef CTX_MAGIC static int CTX_MAGIC; @@ -740,18 +739,17 @@ PUBLIC int LuaCallFunc (CtlSourceT *source, CtlActionT *action, json_object *que PUBLIC int luaLoadScript(const char *luaScriptPath) { - int err = luaL_loadfile(luaState, luaScriptPath); - if (err) { - AFB_ApiError(source->api, "LUA-DOSCRIPT HOOPs Error in LUA loading scripts=%s err=%s", luaScriptPath, lua_tostring(luaState,-1)); + int err = 0; + + if(!luaScriptPath) + return -1; + + err = luaL_loadfile(luaState, luaScriptPath); + if (err) return err; - } // Script was loaded we need to parse to make it executable err = lua_pcall(luaState, 0, 0, 0); - if (err) { - AFB_ApiError(source->api, "LUA-DOSCRIPT:FAIL to load %s", luaScriptPath); - return err; - } return err; } @@ -804,9 +802,11 @@ STATIC int LuaDoScript(json_object *queryJ, CtlSourceT *source) } } - err = luaLoadScript(luaScriptPath); - if(err) + err = LuaLoadScript(luaScriptPath); + if(err) { + AFB_ApiError(source->api, "LUA-DOSCRIPT HOOPs Error in LUA loading scripts=%s err=%s", luaScriptPath, lua_tostring(luaState,-1)); return err; + } // if no func name given try to deduct from filename if (!func && (func=(char*)GetMidleName(filename))!=NULL) { @@ -1243,12 +1243,12 @@ OnErrorExit: // Register a new L2c list of LUA user plugin commands -PUBLIC void LuaL2cNewLib(luaL_Reg *l2cFunc, int count) { +void LuaL2cNewLib(luaL_Reg *l2cFunc, int count, const char *prefix) { // 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, "L2C"); + lua_setglobal(luaState, prefix); } static const luaL_Reg afbFunction[] = { @@ -1314,84 +1314,4 @@ PUBLIC int LuaConfigLoad (AFB_ApiT apiHandle) { } return 0; - - OnErrorExit: - free(luaState); - return 1; -} - -// Create Binding Event at Init Exec Time -PUBLIC int LuaConfigExec (AFB_ApiT apiHandle, const char* prefix) { - - int err, index; - - // create L2C mapping before any LUA script is loaded - if (ctlLua2cFunc && ctlLua2cFunc->l2cCount) { - LuaL2cNewLib (ctlLua2cFunc->l2cFunc, ctlLua2cFunc->l2cCount); - } - - // search for default policy config files - char fullprefix[CONTROL_MAXPATH_LEN] = ""; - if(prefix) - strncpy (fullprefix, prefix, strlen(prefix)+1); - else - strncat (fullprefix, GetBinderName(), strlen(GetBinderName())); - - strncat (fullprefix, "-", strlen("-")); - - const char *dirList= getenv("CONTROL_LUA_PATH"); - //if (!dirList) dirList=CONTROL_LUA_PATH; - - // 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 - if(luaScriptPathJ) { - 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_ApiError(apiHandle, "LUA-INIT HOOPs invalid config file path = %s", json_object_get_string(entryJ)); - goto OnErrorExit; - } - - char filepath[CONTROL_MAXPATH_LEN]; - strncpy(filepath, fullpath, strlen(fullpath)+1); - strncat(filepath, "/", strlen("/")); - strncat(filepath, filename, strlen(filename)); - err= luaL_loadfile(luaState, filepath); - if (err) { - AFB_ApiError(apiHandle, "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_ApiError(apiHandle, "LUA-LOAD HOOPs Error in LUA exec scripts=%s err=%s", filepath, lua_tostring(luaState,-1)); - goto OnErrorExit; - } else { - AFB_ApiNotice(apiHandle, "LUA-LOAD '%s'", filepath); - } - } - - json_object_put(luaScriptPathJ); - // no policy config found remove control API from binder - if (index == 0) { - AFB_ApiWarning (apiHandle, "POLICY-INIT:WARNING (setenv CONTROL_LUA_PATH) No LUA '%s*.lua' in '%s'", fullprefix, dirList); - } - } - else AFB_ApiWarning (apiHandle, "POLICY-INIT:WARNING (setenv CONTROL_LUA_PATH) No LUA '%s*.lua' in '%s'", fullprefix, dirList); - - AFB_ApiDebug (apiHandle, "Control: LUA Init Done"); - return 0; - - OnErrorExit: - return 1; } diff --git a/ctl-lib/ctl-lua.h b/ctl-lib/ctl-lua.h index cf28dcb..deff9ee 100644 --- a/ctl-lib/ctl-lua.h +++ b/ctl-lib/ctl-lua.h @@ -61,7 +61,7 @@ extern const char *lua_utils; PUBLIC int luaLoadScript(const char *luaScriptPath); PUBLIC int LuaConfigLoad (AFB_ApiT apiHandle); PUBLIC int LuaConfigExec(AFB_ApiT apiHandle, const char * prefix); -PUBLIC void LuaL2cNewLib(luaL_Reg *l2cFunc, int count); +PUBLIC void LuaL2cNewLib(luaL_Reg *l2cFunc, int count, const char *prefix); PUBLIC int Lua2cWrapper(void* luaHandle, char *funcname, Lua2cFunctionT callback); PUBLIC int LuaCallFunc (CtlSourceT *source, CtlActionT *action, json_object *queryJ) ; PUBLIC void ctlapi_lua_docall (afb_req request); diff --git a/ctl-lib/ctl-plugin.c b/ctl-lib/ctl-plugin.c index 3e3e16e..ab9e171 100644 --- a/ctl-lib/ctl-plugin.c +++ b/ctl-lib/ctl-plugin.c @@ -24,12 +24,6 @@ #include "ctl-config.h" -#ifdef CONTROL_SUPPORT_LUA -CtlLua2cFuncT *ctlLua2cFunc = NULL; -#endif - -static CtlPluginT *ctlPlugins = NULL; - PUBLIC int PluginGetCB (AFB_ApiT apiHandle, CtlActionT *action , json_object *callbackJ) { const char *plugin=NULL, *function=NULL; json_object *argsJ; @@ -120,8 +114,8 @@ STATIC int PluginLoadCOne(AFB_ApiT apiHandle, const char *pluginpath, json_objec *lua2cInPlug = (Lua2cWrapperT)DispatchOneL2c; int Lua2cAddOne(luaL_Reg *l2cFunc, const char* l2cName, int index) { - if(ctlLua2cFunc->l2cCount) - {index += ctlLua2cFunc->l2cCount+1;} + if(ctlPlugin->ctlL2cFunc->l2cCount) + {index += ctlPlugin->ctlL2cFunc->l2cCount+1;} char funcName[CONTROL_MAXPATH_LEN]; strncpy(funcName, "lua2c_", strlen ("lua2c_")+1); strncat(funcName, l2cName, strlen (l2cName)); @@ -139,14 +133,18 @@ STATIC int PluginLoadCOne(AFB_ApiT apiHandle, const char *pluginpath, json_objec int count = 0, errCount = 0; luaL_Reg *l2cFunc = NULL; - if(!ctlLua2cFunc) { - ctlLua2cFunc = calloc(1, sizeof(CtlLua2cFuncT)); + if(!ctlPlugin->ctlL2cFunc) { + ctlPlugin->ctlL2cFunc = calloc(1, sizeof(CtlLua2cFuncT)); } + ctlPlugin->ctlL2cFunc->prefix = (lua2c_prefix) ? + lua2c_prefix : + ctlPlugin->uid; + // look on l2c command and push them to LUA if (json_object_get_type(lua2csJ) == json_type_array) { size_t length = json_object_array_length(lua2csJ); - l2cFunc = calloc(length + ctlLua2cFunc->l2cCount + 1, sizeof (luaL_Reg)); + l2cFunc = calloc(length + ctlPlugin->ctlL2cFunc->l2cCount + 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)); @@ -154,7 +152,7 @@ STATIC int PluginLoadCOne(AFB_ApiT apiHandle, const char *pluginpath, json_objec if (err) errCount++; } } else { - l2cFunc = calloc(2 + ctlLua2cFunc->l2cCount, sizeof (luaL_Reg)); + l2cFunc = calloc(2 + ctlPlugin->ctlL2cFunc->l2cCount, sizeof (luaL_Reg)); const char *l2cName = json_object_get_string(lua2csJ); errCount = Lua2cAddOne(l2cFunc, l2cName, count); count++; @@ -163,23 +161,28 @@ STATIC int PluginLoadCOne(AFB_ApiT apiHandle, const char *pluginpath, json_objec AFB_ApiError(apiHandle, "CTL-PLUGIN-LOADONE %d symbols not found in plugin='%s'", errCount, pluginpath); return -1; } - int total = ctlLua2cFunc->l2cCount + count; - if(ctlLua2cFunc->l2cCount) { - for (int offset = ctlLua2cFunc->l2cCount; offset < total; offset++) + int total = ctlPlugin->ctlL2cFunc->l2cCount + count; + if(ctlPlugin->ctlL2cFunc->l2cCount) { + for (int offset = ctlPlugin->ctlL2cFunc->l2cCount; offset < total; offset++) { - int index = offset - ctlLua2cFunc->l2cCount; - l2cFunc[index] = ctlLua2cFunc->l2cFunc[index]; + int index = offset - ctlPlugin->ctlL2cFunc->l2cCount; + l2cFunc[index] = ctlPlugin->ctlL2cFunc->l2cFunc[index]; } - free(ctlLua2cFunc->l2cFunc); + free(ctlPlugin->ctlL2cFunc->l2cFunc); } - ctlLua2cFunc->l2cFunc = l2cFunc; - ctlLua2cFunc->l2cCount = total; + ctlPlugin->ctlL2cFunc->l2cFunc = l2cFunc; + ctlPlugin->ctlL2cFunc->l2cCount = total; + + LuaL2cNewLib(ctlPlugin->ctlL2cFunc->l2cFunc, ctlPlugin->ctlL2cFunc->l2cCount, ctlPlugin->ctlL2cFunc->prefix); } #endif DispatchPluginInstallCbT ctlPluginOnload = dlsym(dlHandle, "CtlPluginOnload"); if (ctlPluginOnload) { ctlPlugin->api = apiHandle; - ctlPlugin->context = (*ctlPluginOnload) (ctlPlugin, handle); + if((*ctlPluginOnload) (ctlPlugin, handle)) { + AFB_ApiError(apiHandle, "Plugin Onload function hasn't finish well. Abort initialization"); + return -1; + } } return 0; @@ -217,17 +220,17 @@ STATIC int LoadFoundPlugins(AFB_ApiT apiHandle, json_object *scanResult, json_ob strncat(pluginpath, "/", strlen ("/")); strncat(pluginpath, filename, strlen (filename)); - if(!strcasecmp(ext, CONTROL_PLUGIN_EXT)) { - if(ext && !strcasecmp(ext, CONTROL_PLUGIN_EXT) && i > 0) { + if(!strcasecmp(ext, CTL_PLUGIN_EXT)) { + if(ext && !strcasecmp(ext, CTL_PLUGIN_EXT) && i > 0) { AFB_ApiWarning(apiHandle, "Plugin multiple instances in searchpath will use %s/%s", fullpath, filename); return 0; } - PluginLoadCOne(apiHandle, pluginpath, lua2csJ, handle, ctlPlugin); + PluginLoadCOne(apiHandle, pluginpath, lua2csJ, lua2c_prefix, handle, ctlPlugin); } - else if(!strcasecmp(ext, CONTROL_SCRIPT_EXT)) { + else if(!strcasecmp(ext, CTL_SCRIPT_EXT)) { ctlPlugin->api = apiHandle; ctlPlugin->context = handle; - luaLoadScript(pluginpath); + LuaLoadScript(pluginpath); } } @@ -281,28 +284,28 @@ STATIC int PluginLoad (AFB_ApiT apiHandle, CtlPluginT *ctlPlugin, json_object *p { int err = 0, i = 0; char *searchPath; - const char *sPath = NULL, *file = NULL; + const char *sPath = NULL, *file = NULL, *lua2c_prefix = NULL; json_object *lua2csJ = NULL, *fileJ = NULL, *pluginPathJ = NULL; // plugin initialises at 1st load further init actions should be place into onload section if (!pluginJ) return 0; - err = wrap_json_unpack(pluginJ, "{ss,s?s,s?s,s?o,s?o !}", + err = wrap_json_unpack(pluginJ, "{ss,s?s,s?s,s?o,s?o,s?s !}", "uid", &ctlPlugin->uid, "info", &ctlPlugin->info, "spath", &sPath, "file", &fileJ, - "lua2c", &lua2csJ); + "lua2c", &lua2csJ, + "lua2c_prefix", &lua2c_prefix); if (err) { AFB_ApiError(apiHandle, "CTL-PLUGIN-LOADONE Plugin missing uid|[info]|file|[ldpath]|[lua2c] in:\n-- %s", json_object_get_string(pluginJ)); goto OnErrorExit; } // if search path not in Json config file, then try default - if(sPath) - searchPath = strdup(sPath); - else - searchPath = GetDefaultSearchPath(); + searchPath = (sPath) ? + strdup(sPath) : + GetDefaultSearchPath(); // default file equal uid if (!fileJ) { @@ -310,12 +313,14 @@ STATIC int PluginLoad (AFB_ApiT apiHandle, CtlPluginT *ctlPlugin, json_object *p if(FindPlugins(apiHandle, searchPath, file, &pluginPathJ)) goto OnErrorExit; LoadFoundPlugins(apiHandle, pluginPathJ, lua2csJ, handle, ctlPlugin); + LoadFoundPlugins(apiHandle, pluginPathJ, lua2csJ, lua2c_prefix, handle, ctlPlugin); } else if(json_object_is_type(fileJ, json_type_string)) { file = json_object_get_string(fileJ); if(FindPlugins(apiHandle, searchPath, file, &pluginPathJ)) goto OnErrorExit; LoadFoundPlugins(apiHandle, pluginPathJ, lua2csJ, handle, ctlPlugin); + LoadFoundPlugins(apiHandle, pluginPathJ, lua2csJ, lua2c_prefix, handle, ctlPlugin); } else if(json_object_is_type(fileJ, json_type_array)) { for(i = 0; i < json_object_array_length(fileJ);++i) { @@ -323,6 +328,7 @@ STATIC int PluginLoad (AFB_ApiT apiHandle, CtlPluginT *ctlPlugin, json_object *p if(FindPlugins(apiHandle, searchPath, file, &pluginPathJ)) goto OnErrorExit; LoadFoundPlugins(apiHandle, pluginPathJ, lua2csJ, handle, ctlPlugin); + LoadFoundPlugins(apiHandle, pluginPathJ, lua2c_prefix, lua2csJ, handle, ctlPlugin); } } diff --git a/ctl-lib/ctl-plugin.h b/ctl-lib/ctl-plugin.h index 5d505ac..85d9788 100644 --- a/ctl-lib/ctl-plugin.h +++ b/ctl-lib/ctl-plugin.h @@ -30,9 +30,6 @@ extern "C" { #include <json-c/json.h> -#define CONTROL_PLUGIN_EXT ".ctlso" -#define CONTROL_SCRIPT_EXT ".lua" - // Waiting for a clean AppFW-V3 API #ifdef USE_API_DYN #define AFB_BINDING_VERSION dyn @@ -165,6 +162,15 @@ extern "C" { #define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x #endif +#ifdef CONTROL_SUPPORT_LUA + typedef struct luaL_Reg luaL_Reg; + + typedef struct CtlLua2cFuncT { + luaL_Reg *l2cFunc; + const char *prefix; + int l2cCount; +} CtlLua2cFuncT; +#endif typedef struct { const char *uid; @@ -177,6 +183,9 @@ typedef struct { AFB_ApiT api; void *dlHandle; void *context; +#ifdef CONTROL_SUPPORT_LUA + CtlLua2cFuncT *ctlL2cFunc; +#endif } CtlPluginT; typedef enum { @@ -227,8 +236,9 @@ typedef struct { } exec; } CtlActionT; +extern CtlPluginT *ctlPlugins; -typedef void*(*DispatchPluginInstallCbT)(CtlPluginT *plugin, void* handle); +typedef int(*DispatchPluginInstallCbT)(CtlPluginT *plugin, void* handle); #define MACRO_STR_VALUE(arg) #arg #define CTLP_CAPI_REGISTER(pluglabel) CtlPluginMagicT CtlPluginMagic={.uid=pluglabel,.magic=CTL_PLUGIN_MAGIC}; struct afb_binding_data_v2; |