From 61f0f263c335ad403c6693a1b8b6f5428ac180a8 Mon Sep 17 00:00:00 2001 From: Fulup Ar Foll Date: Wed, 16 Aug 2017 18:25:05 +0200 Subject: Fixed LUA Nested Table Issues. Added LUA2C for User Defined Plugins --- Controler-afb/ctl-dispatch.c | 583 ++++++++++++++++++++++++++----------------- 1 file changed, 350 insertions(+), 233 deletions(-) (limited to 'Controler-afb/ctl-dispatch.c') diff --git a/Controler-afb/ctl-dispatch.c b/Controler-afb/ctl-dispatch.c index 0594952..22bee27 100644 --- a/Controler-afb/ctl-dispatch.c +++ b/Controler-afb/ctl-dispatch.c @@ -27,7 +27,7 @@ typedef void*(*DispatchPluginInstallCbT)(const char* label, const char*version, const char*info); -static afb_req NULL_AFBREQ={}; +static afb_req NULL_AFBREQ = {}; typedef enum { CTL_DISPATCH_ONLOAD, @@ -42,12 +42,20 @@ typedef struct { } DispatchHandleT; typedef struct { - const char* label; + const char *label; const char *info; - const char *version; void *context; - char *plugin; + char *sharelib; void *dlHandle; + luaL_Reg *l2cFunc; + int l2cCount; +} DispatchPluginT; + +typedef struct { + const char* label; + const char *info; + const char *version; + DispatchPluginT *plugin; DispatchHandleT **onloads; DispatchHandleT **events; DispatchHandleT **controls; @@ -58,295 +66,348 @@ STATIC DispatchConfigT *configHandle = NULL; STATIC int DispatchControlToIndex(DispatchHandleT **controls, const char* controlLabel) { - for (int idx=0; controls[idx]; idx++) { + for (int idx = 0; controls[idx]; idx++) { if (!strcasecmp(controlLabel, controls[idx]->label)) return idx; } return -1; } -STATIC int DispatchOneControl (DispatchHandleT **controls, const char* controlLabel, json_object *queryJ, afb_req request) { +STATIC int DispatchOneControl(DispatchHandleT **controls, const char* controlLabel, json_object *queryJ, afb_req request) { int err; - if(!configHandle->controls) { - AFB_ERROR ("DISPATCH-CTL-API: No Control Action in Json config label=%s version=%s", configHandle->label, configHandle->version); + if (!configHandle) { + AFB_ERROR("DISPATCH-CTL-API: (Hoops/Bug!!!) No Config Loaded"); goto OnErrorExit; } - - int index=DispatchControlToIndex(controls, controlLabel); - if (index<0 || !controls[index]->actions) { - AFB_ERROR ("DISPATCH-CTL-API:NotFound label=%s in Json Control Config File", controlLabel); + + if (!configHandle->controls) { + AFB_ERROR("DISPATCH-CTL-API: No Control Action in Json config label=%s version=%s", configHandle->label, configHandle->version); goto OnErrorExit; - } + } + + int index = DispatchControlToIndex(controls, controlLabel); + if (index < 0 || !controls[index]->actions) { + AFB_ERROR("DISPATCH-CTL-API:NotFound/Error label=%s in Json Control Config File", controlLabel); + goto OnErrorExit; + } + + // Fulup (Bug/Feature) in current version is unique to every onload profile + if (configHandle->plugin && configHandle->plugin->l2cCount) { + LuaL2cNewLib (configHandle->plugin->label, configHandle->plugin->l2cFunc, configHandle->plugin->l2cCount); + } // loop on action for this control - DispatchActionT *actions=controls[index]->actions; - for (int idx=0; actions[idx].label; idx++) { - + DispatchActionT *actions = controls[index]->actions; + for (int idx = 0; actions[idx].label; idx++) { + switch (actions[idx].mode) { - case CTL_MODE_API: { + case CTL_MODE_API: + { json_object *returnJ; - - json_object_get( actions[idx].argsJ); // make sure afb_service_call does not free the argsJ + + json_object_get(actions[idx].argsJ); // make sure afb_service_call does not free the argsJ int err = afb_service_call_sync(actions[idx].api, actions[idx].call, actions[idx].argsJ, &returnJ); if (err) { - static const char*format="DispatchOneControl(Api) api=%s verb=%s args=%s"; + static const char*format = "DispatchOneControl(Api) api=%s verb=%s args=%s"; if (afb_req_is_valid(request))afb_req_fail_f(request, "DISPATCH-CTL-MODE:API", format, actions[idx].label, actions[idx].api, actions[idx].call); - else AFB_ERROR (format, actions[idx].api, actions[idx].call, actions[idx].label); + else AFB_ERROR(format, actions[idx].api, actions[idx].call, actions[idx].label); goto OnErrorExit; } break; } - + +#ifdef CONTROL_SUPPORT_LUA case CTL_MODE_LUA: - err= LuaCallFunc (&actions[idx], queryJ); + err = LuaCallFunc(&actions[idx], queryJ); if (err) { - static const char*format= "DispatchOneControl(Lua) label=%s func=%s args=%s"; + static const char*format = "DispatchOneControl(Lua) label=%s func=%s args=%s"; if (afb_req_is_valid(request)) afb_req_fail_f(request, "DISPATCH-CTL-MODE:Lua", format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ)); - else AFB_ERROR (format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ)); + else AFB_ERROR(format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ)); goto OnErrorExit; } break; - +#endif + case CTL_MODE_CB: - err= (*actions[idx].actionCB) (&actions[idx], queryJ, configHandle->context); + err = (*actions[idx].actionCB) (actions[idx].label, actions[idx].argsJ, queryJ, configHandle->plugin->context); if (err) { - static const char*format="DispatchOneControl(Callback) label%s func=%s args=%s"; - if (afb_req_is_valid(request)) afb_req_fail_f(request, "DISPATCH-CTL-MODE:Cb", format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ)); - else AFB_ERROR (format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ)); + static const char*format = "DispatchOneControl(Callback) label%s func=%s args=%s"; + if (afb_req_is_valid(request)) afb_req_fail_f(request, "DISPATCH-CTL-MODE:Cb", format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ)); + else AFB_ERROR(format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ)); goto OnErrorExit; } break; - - default:{ - static const char*format="DispatchOneControl(unknown) mode control=%s action=%s"; - AFB_ERROR (format, controls[index]->label); + + default: + { + static const char*format = "DispatchOneControl(unknown) mode control=%s action=%s"; + AFB_ERROR(format, controls[index]->label); if (afb_req_is_valid(request))afb_req_fail_f(request, "DISPATCH-CTL-MODE:Unknown", format, controls[index]->label); - } + } } } - + // everything when fine - if(afb_req_is_valid(request))afb_req_success(request,NULL,controls[index]->label); + if (afb_req_is_valid(request))afb_req_success(request, NULL, controls[index]->label); return 0; - - OnErrorExit: + +OnErrorExit: return -1; } // Event name is mapped on control label and executed as a standard control -PUBLIC void DispatchOneEvent(const char *evtLabel, json_object *eventJ){ - DispatchHandleT **events=configHandle->events; - (void)DispatchOneControl(events, evtLabel, eventJ, NULL_AFBREQ); +PUBLIC void DispatchOneEvent(const char *evtLabel, json_object *eventJ) { + DispatchHandleT **events = configHandle->events; + + (void) DispatchOneControl(events, evtLabel, eventJ, NULL_AFBREQ); } // Event name is mapped on control label and executed as a standard control -PUBLIC int DispatchOneOnLoad(const char *onLoadLabel){ - DispatchHandleT **onloads=configHandle->onloads; - int err=DispatchOneControl(onloads, onLoadLabel, NULL, NULL_AFBREQ); +PUBLIC int DispatchOnLoad(const char *onLoadLabel) { + DispatchHandleT **onloads = configHandle->onloads; + + int err = DispatchOneControl(onloads, onLoadLabel, NULL, NULL_AFBREQ); return err; } -PUBLIC void ctlapi_dispatch (char* controlLabel, afb_req request) { - DispatchHandleT **controls=configHandle->controls; - - json_object* queryJ = afb_req_json(request); - (void)DispatchOneControl(controls, controlLabel, queryJ, request); -} +PUBLIC void ctlapi_dispatch(afb_req request) { + DispatchHandleT **controls = configHandle->controls; + json_object *queryJ, *argsJ; + const char *target; + + queryJ = afb_req_json(request); + int err = wrap_json_unpack(queryJ, "{s:s, s:o !}", "target", &target, "args", &argsJ); + if (err) { + afb_req_fail_f(request, "CTL-DISPTACH-INVALID", "missing target or args not a valid json object query=%s", json_object_get_string(queryJ)); + goto OnErrorExit; + } + + (void) DispatchOneControl(controls, target, argsJ, request); + +OnErrorExit: + return; +} + +// Wrapper to Lua2c plugin command add context dans delegate to LuaWrapper +PUBLIC int DispatchOneL2c(lua_State* luaState, char *funcname, Lua2cFunctionT callback) { +#ifndef CONTROL_SUPPORT_LUA + AFB_ERROR("DISPATCH-ONE-L2C: LUA support not selected (cf:CONTROL_SUPPORT_LUA) in config.cmake"); + return 1; +#else + int err=Lua2cWrapper(luaState, funcname, callback, configHandle->plugin->context); + return err; +#endif +} + // List Avaliable Configuration Files -PUBLIC void ctlapi_config (struct afb_req request) { + +PUBLIC void ctlapi_config(struct afb_req request) { json_object*tmpJ; char *dirList; - + json_object* queryJ = afb_req_json(request); - if (queryJ && json_object_object_get_ex (queryJ, "cfgpath" , &tmpJ)) { - dirList = strdup (json_object_get_string(tmpJ)); - } else { - dirList = strdup (CONTROL_CONFIG_PATH); - AFB_NOTICE ("CONFIG-MISSING: use default CONTROL_CONFIG_PATH=%s", CONTROL_CONFIG_PATH); + if (queryJ && json_object_object_get_ex(queryJ, "cfgpath", &tmpJ)) { + dirList = strdup(json_object_get_string(tmpJ)); + } else { + dirList = strdup(CONTROL_CONFIG_PATH); + AFB_NOTICE("CONFIG-MISSING: use default CONTROL_CONFIG_PATH=%s", CONTROL_CONFIG_PATH); } - + // get list of config file struct json_object *responseJ = ScanForConfig(dirList, CTL_SCAN_RECURSIVE, "onload", "json"); - + if (json_object_array_length(responseJ) == 0) { - afb_req_fail(request, "CONFIGPATH:EMPTY", "No Config Found in CONTROL_CONFIG_PATH"); + afb_req_fail(request, "CONFIGPATH:EMPTY", "No Config Found in CONTROL_CONFIG_PATH"); } else { afb_req_success(request, responseJ, NULL); } - + return; } // unpack individual action object -STATIC int DispatchLoadOneAction (DispatchConfigT *controlConfig, json_object *actionJ, DispatchActionT *action) { - char *api=NULL, *verb=NULL, *callback=NULL, *lua=NULL; - int err, modeCount=0; - err= wrap_json_unpack(actionJ, "{ss,s?s,s?s,s?s,s?s,s?s,s?o !}" - , "label",&action->label, "info",&action->info, "callback",&callback, "lua", &lua, "api",&api, "verb", &verb, "args",&action->argsJ); +STATIC int DispatchLoadOneAction(DispatchConfigT *controlConfig, json_object *actionJ, DispatchActionT *action) { + char *api = NULL, *verb = NULL, *callback = NULL, *lua = NULL; + int err, modeCount = 0; + + err = wrap_json_unpack(actionJ, "{ss,s?s,s?s,s?s,s?s,s?s,s?o !}" + , "label", &action->label, "info", &action->info, "callback", &callback, "lua", &lua, "api", &api, "verb", &verb, "args", &action->argsJ); if (err) { - AFB_ERROR ("DISPATCH-LOAD-ACTION Missing something label|info|callback|lua|(api+verb)|args in %s", json_object_get_string(actionJ)); + AFB_ERROR("DISPATCH-LOAD-ACTION Missing something label|info|callback|lua|(api+verb)|args in %s", json_object_get_string(actionJ)); goto OnErrorExit; } if (lua) { action->mode = CTL_MODE_LUA; - action->call=lua; + action->call = lua; modeCount++; } if (api && verb) { action->mode = CTL_MODE_API; - action->api=api; - action->call=verb; + action->api = api; + action->call = verb; modeCount++; } - if (callback && controlConfig->dlHandle) { + if (callback && controlConfig->plugin) { action->mode = CTL_MODE_CB; - action->call=callback; + action->call = callback; modeCount++; - action->actionCB = dlsym(controlConfig->dlHandle, callback); + action->actionCB = dlsym(controlConfig->plugin->dlHandle, callback); if (!action->actionCB) { - AFB_ERROR ("DISPATCH-LOAD-ACTION fail to find calbback=%s in %s", callback, controlConfig->plugin); + AFB_ERROR("DISPATCH-LOAD-ACTION fail to find calbback=%s in %s", callback, controlConfig->plugin->sharelib); goto OnErrorExit; } } // make sure at least one mode is selected if (modeCount == 0) { - AFB_ERROR ("DISPATCH-LOAD-ACTION No Action Selected lua|callback|(api+verb) in %s", json_object_get_string(actionJ)); + AFB_ERROR("DISPATCH-LOAD-ACTION No Action Selected lua|callback|(api+verb) in %s", json_object_get_string(actionJ)); goto OnErrorExit; - } + } if (modeCount > 1) { - AFB_ERROR ("DISPATCH-LOAD-ACTION:ToMany arguments lua|callback|(api+verb) in %s", json_object_get_string(actionJ)); + AFB_ERROR("DISPATCH-LOAD-ACTION:ToMany arguments lua|callback|(api+verb) in %s", json_object_get_string(actionJ)); goto OnErrorExit; - } - return 0; - + } + return 0; + OnErrorExit: - return -1; + return -1; }; -STATIC DispatchActionT *DispatchLoadActions (DispatchConfigT *controlConfig, json_object *actionsJ) { +STATIC DispatchActionT *DispatchLoadActions(DispatchConfigT *controlConfig, json_object *actionsJ) { int err; DispatchActionT *actions; - + // action array is close with a nullvalue; if (json_object_get_type(actionsJ) == json_type_array) { int count = json_object_array_length(actionsJ); - actions = calloc (count+1, sizeof(DispatchActionT)); - - for (int idx=0; idx < count; idx++) { + actions = calloc(count + 1, sizeof (DispatchActionT)); + + for (int idx = 0; idx < count; idx++) { json_object *actionJ = json_object_array_get_idx(actionsJ, idx); - err = DispatchLoadOneAction (controlConfig, actionJ, &actions[idx]); + err = DispatchLoadOneAction(controlConfig, actionJ, &actions[idx]); if (err) goto OnErrorExit; } - + } else { - actions = calloc (2, sizeof(DispatchActionT)); - err = DispatchLoadOneAction (controlConfig, actionsJ, &actions[0]); + actions = calloc(2, sizeof (DispatchActionT)); + err = DispatchLoadOneAction(controlConfig, actionsJ, &actions[0]); if (err) goto OnErrorExit; } - + return actions; - - OnErrorExit: + +OnErrorExit: return NULL; - + } -STATIC DispatchHandleT *DispatchLoadControl (DispatchConfigT *controlConfig, json_object *controlJ) { - json_object *actionsJ; +STATIC DispatchHandleT *DispatchLoadControl(DispatchConfigT *controlConfig, json_object *controlJ) { + json_object *actionsJ, *permissionsJ; int err; - - DispatchHandleT *dispatchHandle = calloc (1, sizeof(DispatchHandleT)); - err= wrap_json_unpack(controlJ, "{ss,s?s,so !}", "label",&dispatchHandle->label, "info",&dispatchHandle->info, "actions",&actionsJ); + + DispatchHandleT *dispatchHandle = calloc(1, sizeof (DispatchHandleT)); + err = wrap_json_unpack(controlJ, "{ss,s?s,s?o, so !}", "label", &dispatchHandle->label, "info", &dispatchHandle->info + , "permissions", &permissionsJ, "actions", &actionsJ); if (err) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:CONTROL Missing something label|[info]|actions in %s", json_object_get_string(controlJ)); + AFB_ERROR("DISPATCH-LOAD-CONFIG:CONTROL Missing something label|[info]|actions in %s", json_object_get_string(controlJ)); goto OnErrorExit; } - dispatchHandle->actions= DispatchLoadActions(controlConfig, actionsJ); + dispatchHandle->actions = DispatchLoadActions(controlConfig, actionsJ); if (!dispatchHandle->actions) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:CONTROL Error when parsing actions %s", dispatchHandle->label); - goto OnErrorExit; + AFB_ERROR("DISPATCH-LOAD-CONFIG:CONTROL Error when parsing actions %s", dispatchHandle->label); + goto OnErrorExit; } return dispatchHandle; - - OnErrorExit: - return NULL; + +OnErrorExit: + return NULL; } -STATIC DispatchHandleT *DispatchLoadOnload (DispatchConfigT *controlConfig, json_object *onloadJ) { - json_object *actionsJ=NULL, *requireJ=NULL; +STATIC DispatchHandleT *DispatchLoadOnload(DispatchConfigT *controlConfig, json_object *onloadJ) { + json_object *actionsJ = NULL, *requireJ = NULL, *pluginJ = NULL; int err; - - DispatchHandleT *dispatchHandle = calloc (1, sizeof(DispatchHandleT)); - err= wrap_json_unpack(onloadJ, "{ss,s?s,s?s,s?o,s?o !}", - "label",&dispatchHandle->label, "info",&dispatchHandle->info, "plugin", &controlConfig->plugin, "require", &requireJ, "actions",&actionsJ); + + DispatchHandleT *dispatchHandle = calloc(1, sizeof (DispatchHandleT)); + err = wrap_json_unpack(onloadJ, "{ss,s?s,s?o,s?o,s?o !}", + "label", &dispatchHandle->label, "info", &dispatchHandle->info, "plugin", &pluginJ, "require", &requireJ, "actions", &actionsJ); if (err) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:ONLOAD Missing something label|[info]|[plugin]|[actions] in %s", json_object_get_string(onloadJ)); + AFB_ERROR("DISPATCH-LOAD-CONFIG:ONLOAD Missing something label|[info]|[plugin]|[actions] in %s", json_object_get_string(onloadJ)); goto OnErrorExit; } // best effort to initialise everything before starting if (requireJ) { - void DispatchRequireOneApi (json_object *bindindJ) { + void DispatchRequireOneApi(json_object * bindindJ) { const char* requireBinding = json_object_get_string(bindindJ); err = afb_daemon_require_api(requireBinding, 1); if (err) { - AFB_WARNING ("DISPATCH-LOAD-CONFIG:REQUIRE Fail to get=%s", requireBinding); + AFB_WARNING("DISPATCH-LOAD-CONFIG:REQUIRE Fail to get=%s", requireBinding); } } if (json_object_get_type(requireJ) == json_type_array) { - for (int idx=0; idx < json_object_array_length(requireJ); idx++) { - DispatchRequireOneApi (json_object_array_get_idx(requireJ, idx)); + for (int idx = 0; idx < json_object_array_length(requireJ); idx++) { + DispatchRequireOneApi(json_object_array_get_idx(requireJ, idx)); } } else { - DispatchRequireOneApi (requireJ); + DispatchRequireOneApi(requireJ); } } - if (controlConfig->plugin) { + if (pluginJ) { + json_object *lua2csJ = NULL; + DispatchPluginT *dPlugin= calloc(1, sizeof(DispatchPluginT)); + controlConfig->plugin = dPlugin; + + err = wrap_json_unpack(pluginJ, "{ss,s?s,ss,s?o!}", + "label", &dPlugin->label, "info", &dPlugin->info, "sharelib", &dPlugin->sharelib, "lua2c", &lua2csJ); + if (err) { + AFB_ERROR("DISPATCH-LOAD-CONFIG:ONLOAD Plugin missing label|[info]|sharelib|[lua2c] in %s", json_object_get_string(onloadJ)); + goto OnErrorExit; + } // search for default policy config file - json_object *pluginPathJ = ScanForConfig(CONTROL_PLUGIN_PATH , CTL_SCAN_RECURSIVE, controlConfig->plugin, NULL); + json_object *pluginPathJ = ScanForConfig(CONTROL_PLUGIN_PATH, CTL_SCAN_RECURSIVE, dPlugin->sharelib, NULL); if (!pluginPathJ || json_object_array_length(pluginPathJ) == 0) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:PLUGIN Missing plugin=%s in path=%s", controlConfig->plugin, CONTROL_PLUGIN_PATH); - goto OnErrorExit; + AFB_ERROR("DISPATCH-LOAD-CONFIG:PLUGIN Missing plugin=%s in path=%s", dPlugin->sharelib, CONTROL_PLUGIN_PATH); + 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); + char *filename; + char*fullpath; + err = wrap_json_unpack(json_object_array_get_idx(pluginPathJ, 0), "{s:s, s:s !}", "fullpath", &fullpath, "filename", &filename); if (err) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:PLUGIN HOOPs invalid plugin file path = %s", json_object_get_string(pluginPathJ)); + AFB_ERROR("DISPATCH-LOAD-CONFIG:PLUGIN HOOPs invalid plugin file path = %s", json_object_get_string(pluginPathJ)); goto OnErrorExit; } if (json_object_array_length(pluginPathJ) > 1) { - AFB_WARNING ("DISPATCH-LOAD-CONFIG:PLUGIN plugin multiple instances in searchpath will use %s/%s", fullpath, filename); + AFB_WARNING("DISPATCH-LOAD-CONFIG:PLUGIN plugin multiple instances in searchpath will use %s/%s", fullpath, filename); } char pluginpath[CONTROL_MAXPATH_LEN]; - strncpy(pluginpath, fullpath, sizeof(pluginpath)); - strncat(pluginpath, "/", sizeof(pluginpath)); - strncat(pluginpath, filename, sizeof(pluginpath)); - controlConfig->dlHandle = dlopen(pluginpath, RTLD_NOW); - if (!controlConfig->dlHandle) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:PLUGIN Fail to load pluginpath=%s err= %s", pluginpath, dlerror()); + strncpy(pluginpath, fullpath, sizeof (pluginpath)); + strncat(pluginpath, "/", sizeof (pluginpath)); + strncat(pluginpath, filename, sizeof (pluginpath)); + dPlugin->dlHandle = dlopen(pluginpath, RTLD_NOW); + if (!dPlugin->dlHandle) { + AFB_ERROR("DISPATCH-LOAD-CONFIG:PLUGIN Fail to load pluginpath=%s err= %s", pluginpath, dlerror()); goto OnErrorExit; } - CtlPluginMagicT *ctlPluginMagic = (CtlPluginMagicT*)dlsym(controlConfig->dlHandle, "CtlPluginMagic"); + CtlPluginMagicT *ctlPluginMagic = (CtlPluginMagicT*) dlsym(dPlugin->dlHandle, "CtlPluginMagic"); if (!ctlPluginMagic || ctlPluginMagic->magic != CTL_PLUGIN_MAGIC) { AFB_ERROR("DISPATCH-LOAD-CONFIG:Plugin symbol'CtlPluginMagic' missing or != CTL_PLUGIN_MAGIC plugin=%s", pluginpath); goto OnErrorExit; @@ -355,173 +416,229 @@ STATIC DispatchHandleT *DispatchLoadOnload (DispatchConfigT *controlConfig, jso } // Jose hack to make verbosity visible from sharelib - struct afb_binding_data_v2 *afbHidenData = dlsym(controlConfig->dlHandle, "afbBindingV2data"); - if (afbHidenData) *afbHidenData = afbBindingV2data; + struct afb_binding_data_v2 *afbHidenData = dlsym(dPlugin->dlHandle, "afbBindingV2data"); + if (afbHidenData) *afbHidenData = afbBindingV2data; + + // Push lua2cWrapper @ into plugin + Lua2cWrapperT *lua2cInPlug = dlsym(dPlugin->dlHandle, "Lua2cWrap"); +#ifndef CONTROL_SUPPORT_LUA + if (lua2cInPlug) *lua2cInPlug = NULL; +#else + // Lua2cWrapper is part of binder and not expose to dynamic link + if (lua2cInPlug) *lua2cInPlug = DispatchOneL2c; + + { + int Lua2cAddOne(luaL_Reg *l2cFunc, const char* l2cName, int index) { + char funcName[CONTROL_MAXPATH_LEN]; + strncpy(funcName, "lua2c_", sizeof(funcName)); + strncat(funcName, l2cName, sizeof(funcName)); + + Lua2cFunctionT l2cFunction= (Lua2cFunctionT)dlsym(dPlugin->dlHandle, funcName); + if (!l2cFunction) { + AFB_ERROR("DISPATCH-LOAD-CONFIG:Plugin symbol'%s' missing err=%s", funcName, dlerror()); + return 1; + } + l2cFunc[index].func=(void*)l2cFunction; + l2cFunc[index].name=strdup(l2cName); + + return 0; + } - DispatchPluginInstallCbT ctlPluginOnload = dlsym(controlConfig->dlHandle, "CtlPluginOnload"); + int errCount = 0; + luaL_Reg *l2cFunc=NULL; + int count=0; + + // look on l2c command and push them to LUA + if (json_object_get_type(lua2csJ) == json_type_array) { + int length = json_object_array_length(lua2csJ); + l2cFunc = calloc(length + 1, sizeof (luaL_Reg)); + for (count=0; count < length; count++) { + int err; + const char *l2cName = json_object_get_string(json_object_array_get_idx(lua2csJ, count)); + err = Lua2cAddOne(l2cFunc, l2cName, count); + if (err) errCount++; + } + } else { + l2cFunc = calloc(2, sizeof (luaL_Reg)); + const char *l2cName = json_object_get_string(lua2csJ); + errCount = Lua2cAddOne(l2cFunc, l2cName, 0); + count=1; + } + if (errCount) { + AFB_ERROR("DISPATCH-LOAD-CONFIG:Plugin %d symbols not found in plugin='%s'", errCount, pluginpath); + goto OnErrorExit; + } else { + dPlugin->l2cFunc= l2cFunc; + dPlugin->l2cCount= count; + } + } +#endif + DispatchPluginInstallCbT ctlPluginOnload = dlsym(dPlugin->dlHandle, "CtlPluginOnload"); if (ctlPluginOnload) { - controlConfig->context = (*ctlPluginOnload) (controlConfig->label, controlConfig->version, controlConfig->info); + dPlugin->context = (*ctlPluginOnload) (controlConfig->label, controlConfig->version, controlConfig->info); } } - dispatchHandle->actions= DispatchLoadActions(controlConfig, actionsJ); + dispatchHandle->actions = DispatchLoadActions(controlConfig, actionsJ); if (!dispatchHandle->actions) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:ONLOAD Error when parsing actions %s", dispatchHandle->label); - goto OnErrorExit; + AFB_ERROR("DISPATCH-LOAD-CONFIG:ONLOAD Error when parsing actions %s", dispatchHandle->label); + goto OnErrorExit; } return dispatchHandle; - - OnErrorExit: - return NULL; + +OnErrorExit: + return NULL; } -STATIC DispatchConfigT *DispatchLoadConfig (const char* filepath) { +STATIC DispatchConfigT *DispatchLoadConfig(const char* filepath) { json_object *controlConfigJ, *ignoreJ; int err; - + // Load JSON file - controlConfigJ= json_object_from_file(filepath); + controlConfigJ = json_object_from_file(filepath); if (!controlConfigJ) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:JsonLoad invalid JSON %s ", filepath); + AFB_ERROR("DISPATCH-LOAD-CONFIG:JsonLoad invalid JSON %s ", filepath); goto OnErrorExit; } - - AFB_INFO ("DISPATCH-LOAD-CONFIG: loading config filepath=%s", filepath); - - json_object *metadataJ=NULL, *onloadsJ=NULL, *controlsJ=NULL, *eventsJ=NULL; - err= wrap_json_unpack(controlConfigJ, "{s?o,so,s?o,s?o,s?o !}", "$schema", &ignoreJ, "metadata",&metadataJ, "onload",&onloadsJ, "controls",&controlsJ, "events",&eventsJ); + + AFB_INFO("DISPATCH-LOAD-CONFIG: loading config filepath=%s", filepath); + + json_object *metadataJ = NULL, *onloadsJ = NULL, *controlsJ = NULL, *eventsJ = NULL; + err = wrap_json_unpack(controlConfigJ, "{s?o,so,s?o,s?o,s?o !}", "$schema", &ignoreJ, "metadata", &metadataJ, "onload", &onloadsJ, "controls", &controlsJ, "events", &eventsJ); if (err) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG Missing something metadata|[onload]|[controls]|[events] in %s", json_object_get_string(controlConfigJ)); + AFB_ERROR("DISPATCH-LOAD-CONFIG Missing something metadata|[onload]|[controls]|[events] in %s", json_object_get_string(controlConfigJ)); goto OnErrorExit; } - - DispatchConfigT *controlConfig = calloc (1, sizeof(DispatchConfigT)); + + DispatchConfigT *controlConfig = calloc(1, sizeof (DispatchConfigT)); if (metadataJ) { - err= wrap_json_unpack(metadataJ, "{ss,s?s,ss !}", "label", &controlConfig->label, "info",&controlConfig->info, "version",&controlConfig->version); + err = wrap_json_unpack(metadataJ, "{ss,s?s,ss !}", "label", &controlConfig->label, "info", &controlConfig->info, "version", &controlConfig->version); if (err) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:METADATA Missing something label|version|[label] in %s", json_object_get_string(metadataJ)); + AFB_ERROR("DISPATCH-LOAD-CONFIG:METADATA Missing something label|version|[label] in %s", json_object_get_string(metadataJ)); goto OnErrorExit; } - } - + } + if (onloadsJ) { DispatchHandleT *dispatchHandle; - + if (json_object_get_type(onloadsJ) != json_type_array) { - controlConfig->onloads = (DispatchHandleT**) calloc (2, sizeof(void*)); - dispatchHandle = DispatchLoadOnload (controlConfig, onloadsJ); - controlConfig->onloads[0]= dispatchHandle; - } else { - int length= json_object_array_length(onloadsJ); - controlConfig->onloads = (DispatchHandleT**) calloc (length+1, sizeof(void*)); - - for (int jdx=0; jdx< length; jdx++) { - json_object *onloadJ = json_object_array_get_idx(onloadsJ,jdx); - dispatchHandle = DispatchLoadOnload (controlConfig, onloadJ); - controlConfig->onloads[jdx]= dispatchHandle; + controlConfig->onloads = (DispatchHandleT**) calloc(2, sizeof (void*)); + dispatchHandle = DispatchLoadOnload(controlConfig, onloadsJ); + controlConfig->onloads[0] = dispatchHandle; + } else { + int length = json_object_array_length(onloadsJ); + controlConfig->onloads = (DispatchHandleT**) calloc(length + 1, sizeof (void*)); + + for (int jdx = 0; jdx < length; jdx++) { + json_object *onloadJ = json_object_array_get_idx(onloadsJ, jdx); + dispatchHandle = DispatchLoadOnload(controlConfig, onloadJ); + controlConfig->onloads[jdx] = dispatchHandle; } - } + } } - + if (controlsJ) { DispatchHandleT *dispatchHandle; - + if (json_object_get_type(controlsJ) != json_type_array) { - controlConfig->controls = (DispatchHandleT**) calloc (2, sizeof(void*)); - dispatchHandle = DispatchLoadControl (controlConfig, controlsJ); - controlConfig->controls[0]= dispatchHandle; - } else { - int length= json_object_array_length(controlsJ); - controlConfig->controls = (DispatchHandleT**) calloc (length+1, sizeof(void*)); - - for (int jdx=0; jdx< length; jdx++) { - json_object *controlJ = json_object_array_get_idx(controlsJ,jdx); - dispatchHandle = DispatchLoadControl (controlConfig, controlJ); - controlConfig->controls[jdx]= dispatchHandle; + controlConfig->controls = (DispatchHandleT**) calloc(2, sizeof (void*)); + dispatchHandle = DispatchLoadControl(controlConfig, controlsJ); + controlConfig->controls[0] = dispatchHandle; + } else { + int length = json_object_array_length(controlsJ); + controlConfig->controls = (DispatchHandleT**) calloc(length + 1, sizeof (void*)); + + for (int jdx = 0; jdx < length; jdx++) { + json_object *controlJ = json_object_array_get_idx(controlsJ, jdx); + dispatchHandle = DispatchLoadControl(controlConfig, controlJ); + controlConfig->controls[jdx] = dispatchHandle; } - } + } } - + if (eventsJ) { DispatchHandleT *dispatchHandle; - + if (json_object_get_type(eventsJ) != json_type_array) { - controlConfig->events = (DispatchHandleT**) calloc (2, sizeof(void*)); - dispatchHandle = DispatchLoadControl (controlConfig, eventsJ); - controlConfig->events[0]= dispatchHandle; - } else { - int length= json_object_array_length(eventsJ); - controlConfig->events = (DispatchHandleT**) calloc (length+1, sizeof(void*)); - - for (int jdx=0; jdx< length; jdx++) { - json_object *eventJ = json_object_array_get_idx(eventsJ,jdx); - dispatchHandle = DispatchLoadControl (controlConfig, eventJ); - controlConfig->events[jdx]= dispatchHandle; + controlConfig->events = (DispatchHandleT**) calloc(2, sizeof (void*)); + dispatchHandle = DispatchLoadControl(controlConfig, eventsJ); + controlConfig->events[0] = dispatchHandle; + } else { + int length = json_object_array_length(eventsJ); + controlConfig->events = (DispatchHandleT**) calloc(length + 1, sizeof (void*)); + + for (int jdx = 0; jdx < length; jdx++) { + json_object *eventJ = json_object_array_get_idx(eventsJ, jdx); + dispatchHandle = DispatchLoadControl(controlConfig, eventJ); + controlConfig->events[jdx] = dispatchHandle; } } } - + return controlConfig; - + OnErrorExit: return NULL; } // Load default config file at init -PUBLIC int DispatchInit () { - int index, err, luaLoaded=0; + +PUBLIC int DispatchInit() { + int index, err, luaLoaded = 0; char controlFile [CONTROL_MAXPATH_LEN]; - - strncpy (controlFile,CONTROL_CONFIG_PRE, CONTROL_MAXPATH_LEN); - strncat (controlFile,"-", CONTROL_MAXPATH_LEN); - strncat (controlFile,GetBinderName(), CONTROL_MAXPATH_LEN); - + + strncpy(controlFile, CONTROL_CONFIG_PRE, CONTROL_MAXPATH_LEN); + strncat(controlFile, "-", CONTROL_MAXPATH_LEN); + strncat(controlFile, GetBinderName(), CONTROL_MAXPATH_LEN); + // search for default dispatch config file - json_object* responseJ = ScanForConfig(CONTROL_CONFIG_PATH, CTL_SCAN_RECURSIVE,controlFile, "json"); + json_object* responseJ = ScanForConfig(CONTROL_CONFIG_PATH, 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; - err= wrap_json_unpack (entryJ, "{s:s, s:s !}", "fullpath", &fullpath,"filename", &filename); + for (index = 0; index < json_object_array_length(responseJ); index++) { + json_object *entryJ = json_object_array_get_idx(responseJ, index); + + char *filename; + char*fullpath; + err = wrap_json_unpack(entryJ, "{s:s, s:s !}", "fullpath", &fullpath, "filename", &filename); if (err) { - AFB_ERROR ("DISPATCH-INIT HOOPs invalid JSON entry= %s", json_object_get_string(entryJ)); + AFB_ERROR("DISPATCH-INIT HOOPs invalid JSON entry= %s", json_object_get_string(entryJ)); goto OnErrorExit; } if (index == 0) { if (strcasestr(filename, controlFile)) { char filepath[CONTROL_MAXPATH_LEN]; - strncpy(filepath, fullpath, sizeof(filepath)); - strncat(filepath, "/", sizeof(filepath)); - strncat(filepath, filename, sizeof(filepath)); - configHandle = DispatchLoadConfig (filepath); + strncpy(filepath, fullpath, sizeof (filepath)); + strncat(filepath, "/", sizeof (filepath)); + strncat(filepath, filename, sizeof (filepath)); + configHandle = DispatchLoadConfig(filepath); if (!configHandle) { - AFB_ERROR ("DISPATCH-INIT:ERROR Fail loading [%s]", filepath); + AFB_ERROR("DISPATCH-INIT:ERROR Fail loading [%s]", filepath); goto OnErrorExit; } - luaLoaded=1; + luaLoaded = 1; break; } } else { - AFB_WARNING ("DISPATCH-INIT:WARNING Secondary Control Config Ignored %s/%s", fullpath, filename); + AFB_WARNING("DISPATCH-INIT:WARNING Secondary Control Config Ignored %s/%s", fullpath, filename); } } - + // no dispatch config found remove control API from binder - if (!luaLoaded) { - AFB_WARNING ("DISPATCH-INIT:WARNING Not Found Control dispatch file [%s]", controlFile); + if (!luaLoaded) { + AFB_WARNING("DISPATCH-INIT:WARNING Not Found Control dispatch file [%s]", controlFile); } - - AFB_NOTICE ("DISPATCH-INIT:SUCCES: Audio Control Dispatch Init"); + + AFB_NOTICE("DISPATCH-INIT:SUCCES: Audio Control Dispatch Init"); return 0; - + OnErrorExit: - AFB_NOTICE ("DISPATCH-INIT:ERROR: Audio Control Dispatch Init"); - return 1; + AFB_NOTICE("DISPATCH-INIT:ERROR: Audio Control Dispatch Init"); + return 1; } - - + + -- cgit 1.2.3-korg