diff options
author | fulup <fulup.arfoll@iot.bzh> | 2017-08-11 19:44:21 +0200 |
---|---|---|
committer | fulup <fulup.arfoll@iot.bzh> | 2017-08-11 19:44:21 +0200 |
commit | b65178642727536972d0c04e53b2310be58beb2e (patch) | |
tree | f06f8773ce44f8320e9e86cee60e59e1597d6b78 | |
parent | c13952824e2cc110b9405e1bc9017801dd938ac0 (diff) |
Almost working version with Json Config, Lua script and sharelib callbacks.
-rw-r--r-- | Controler-afb/ctl-binding.c | 6 | ||||
-rw-r--r-- | Controler-afb/ctl-binding.h | 27 | ||||
-rw-r--r-- | Controler-afb/ctl-dispatch.c | 209 | ||||
-rw-r--r-- | Controler-afb/ctl-lua.c | 59 | ||||
-rw-r--r-- | Controler-afb/ctl-plugin-sample.c | 65 | ||||
-rw-r--r-- | conf.d/cmake/config.cmake | 4 | ||||
-rw-r--r-- | conf.d/ctl-rules/onload-control-policy.json | 109 | ||||
-rw-r--r-- | conf.d/ctl-rules/onload-control-script.lua | 9 | ||||
-rw-r--r-- | htdocs/audio-control.html | 6 | ||||
-rw-r--r-- | nbproject/configurations.xml | 18 |
10 files changed, 352 insertions, 160 deletions
diff --git a/Controler-afb/ctl-binding.c b/Controler-afb/ctl-binding.c index fe9388f..dc225a4 100644 --- a/Controler-afb/ctl-binding.c +++ b/Controler-afb/ctl-binding.c @@ -31,17 +31,17 @@ PUBLIC void ctlapi_navigation (afb_req request) { - ctlapi_dispatch (CTLAPI_NAVIGATION, request); + ctlapi_dispatch ("NAVIGATION", request); } PUBLIC void ctlapi_multimedia (afb_req request) { - ctlapi_dispatch (CTLAPI_MULTIMEDIA, request); + ctlapi_dispatch ("MULTIMEDIA", request); } PUBLIC void ctlapi_emergency (afb_req request) { - ctlapi_dispatch (CTLAPI_EMERGENCY, request); + ctlapi_dispatch ("EMERGENCY", request); } PUBLIC void ctlapi_monitor (afb_req request) { diff --git a/Controler-afb/ctl-binding.h b/Controler-afb/ctl-binding.h index abcb2f4..deef93c 100644 --- a/Controler-afb/ctl-binding.h +++ b/Controler-afb/ctl-binding.h @@ -28,6 +28,13 @@ #endif #define STATIC static +// sharelib ctl-plugin* +typedef struct { + long magic; + char *label; +} CtlPluginMagicT; + +#define CTL_PLUGIN_REGISTER(pluglabel) CtlPluginMagicT CtlPluginMagic={.magic=CTL_PLUGIN_MAGIC,.label=pluglabel}; struct afb_binding_data_v2; // polctl-binding.c PUBLIC int CtlBindingInit (); @@ -44,14 +51,6 @@ PUBLIC void ctlapi_event_test (afb_req request); // ----------- typedef enum { - CTLAPI_NAVIGATION, - CTLAPI_MULTIMEDIA, - CTLAPI_EMERGENCY, - - CTL_NONE=-1 -} DispatchCtlEnumT; - -typedef enum { CTL_SCAN_FLAT=0, CTL_SCAN_RECURSIVE=1, } CtlScanDirModeT; @@ -71,15 +70,23 @@ typedef struct DispatchActionS{ const char* call; json_object *argsJ; int timeout; - json_object* (*actionCB)(struct DispatchActionS *action,json_object *response, void *context); + int (*actionCB)(afb_req request, struct DispatchActionS *action, void *context); } DispatchActionT; PUBLIC int DispatchInit(void); -PUBLIC void ctlapi_dispatch (DispatchCtlEnumT control, afb_req request); +PUBLIC void ctlapi_dispatch (char* control, afb_req request); // ctl-lua.c + +typedef enum { + LUA_DOCALL, + LUA_DOSTRING, + LUA_DOSCRIPT, +} LuaDoActionT; + PUBLIC int LuaLibInit (); PUBLIC json_object* ScanForConfig (char* searchPath, CtlScanDirModeT mode, char *pre, char *ext); +PUBLIC int LuaCallFunc (afb_req request, DispatchActionT *action); PUBLIC void ctlapi_lua_docall (afb_req request); PUBLIC void ctlapi_lua_dostring (afb_req request); PUBLIC void ctlapi_lua_doscript (afb_req request); diff --git a/Controler-afb/ctl-dispatch.c b/Controler-afb/ctl-dispatch.c index 4fa1844..8fdf46e 100644 --- a/Controler-afb/ctl-dispatch.c +++ b/Controler-afb/ctl-dispatch.c @@ -31,7 +31,6 @@ typedef void*(*DispatchPluginInstallCbT)(const char* label, const char*version, typedef struct { const char* label; const char *info; - const char *version; DispatchActionT *actions; } DispatchHandleT; @@ -44,17 +43,83 @@ typedef struct { void *dlHandle; DispatchHandleT *onload; DispatchHandleT *events; - DispatchHandleT *controls; + DispatchHandleT **controls; } DispatchConfigT; -STATIC DispatchConfigT *ctlHandle = NULL; +// global config handle +STATIC DispatchConfigT *configHandle = NULL; -PUBLIC void ctlapi_dispatch (DispatchCtlEnumT control, afb_req request) { - json_object*tmpJ; +STATIC int DispatchControlToIndex(char* controlLabel) { + DispatchHandleT **controls=configHandle->controls; + for (int idx=0; controls[idx]; idx++) { + if (!strcasecmp(controlLabel, controls[idx]->label)) return idx; + } + return 0; +} + +PUBLIC void ctlapi_dispatch (char* controlLabel, afb_req request) { + DispatchHandleT **controls=configHandle->controls; + int err; + + if(!configHandle->controls) { + AFB_ERROR ("DISPATCH-CTL-API: No Control Action in Json config label=%s version=%s", configHandle->label, configHandle->version); + goto OnErrorExit; + } - json_object* argsJ= afb_req_json(request); - int done=json_object_object_get_ex(argsJ, "closing", &tmpJ); - if (done) return; + int index=DispatchControlToIndex(controlLabel); + if (!index || !controls[index]->actions) { + AFB_ERROR ("DISPATCH-CTL-API:NotFound label=%s index=%d", controlLabel, index); + goto OnErrorExit; + } else { + AFB_NOTICE("DISPATCH-CTL-API:Found Control=%s", controls[index]->label); + } + + // loop on action for this control + DispatchActionT *actions=controls[index]->actions; + for (int idx=0; actions[idx].label; idx++) { + + switch (actions[idx].mode) { + case CTL_MODE_API: { + json_object *returnJ; + + 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) { + AFB_NOTICE ("DISPATCH-CTL-MODE:Api api=%s verb=%s args=%s", actions[idx].api, actions[idx].call, actions[idx].label); + afb_req_fail_f(request, "DISPATCH-CTL-MODE:Api", "label=%s api=%s verb=%s", actions[idx].label, actions[idx].api, actions[idx].call); + goto OnErrorExit; + } + break; + } + + case CTL_MODE_LUA: + err= LuaCallFunc (request, &actions[idx]); + if (err) { + afb_req_fail_f(request, "DISPATCH-CTL-MODE:Lua", "func=%s args=%s", actions[idx].call, json_object_get_string(actions[idx].argsJ)); + goto OnErrorExit; + } + break; + + case CTL_MODE_CB: + err= (*actions[idx].actionCB) (request, &actions[idx], configHandle->context); + if (err) { + afb_req_fail_f(request, "DISPATCH-CTL-MODE:Cb", "func=%s args=%s", actions[idx].call, json_object_get_string(actions[idx].argsJ)); + goto OnErrorExit; + } + break; + + default: + AFB_ERROR ("DISPATCH-CTL-API:control=%s action=%s", controls[index]->label, actions[idx].label); + afb_req_fail_f(request, "DISPATCH-CTL-MODE:Unknown", "control=%s action=%s", controls[index]->label, actions[idx].label); + } + } + + // everything when fine + afb_req_success(request,NULL,controls[index]->label); + return; + + OnErrorExit: + return; } // List Avaliable Configuration Files @@ -83,12 +148,12 @@ PUBLIC void ctlapi_config (struct afb_req request) { } // unpack individual action object -STATIC int DispatchLoadOneAction (json_object *actionJ, DispatchActionT *action) { - char *api, *verb, *callback, *lua; +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?o,s?s,s?s,s?s !}" - , "label",&action->label, "info",&action->info, "callback",&callback, "lua", &lua, "args",&action->argsJ, "api",&api, "verb", &verb); + 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)); goto OnErrorExit; @@ -107,26 +172,26 @@ STATIC int DispatchLoadOneAction (json_object *actionJ, DispatchActionT *action modeCount++; } - if (callback) { + if (callback && controlConfig->dlHandle) { action->mode = CTL_MODE_CB; action->call=callback; modeCount++; - action->actionCB = dlsym(ctlHandle->dlHandle, callback); + action->actionCB = dlsym(controlConfig->dlHandle, callback); if (!action->actionCB) { - AFB_ERROR ("DISPATCH-LOAD-ACTION fail to find calbback=%s in %s", callback, ctlHandle->plugin); + AFB_ERROR ("DISPATCH-LOAD-ACTION fail to find calbback=%s in %s", callback, controlConfig->plugin); goto OnErrorExit; } } // make sure at least one mode is selected if (modeCount == 0) { - AFB_ERROR ("DISPATCH-LOAD-ACTION Missing something 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 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; @@ -135,7 +200,7 @@ OnErrorExit: return -1; }; -STATIC DispatchActionT *DispatchLoadActions (json_object *actionsJ) { +STATIC DispatchActionT *DispatchLoadActions (DispatchConfigT *controlConfig, json_object *actionsJ) { int err; DispatchActionT *actions; @@ -146,13 +211,13 @@ STATIC DispatchActionT *DispatchLoadActions (json_object *actionsJ) { for (int idx=0; idx < count; idx++) { json_object *actionJ = json_object_array_get_idx(actionsJ, idx); - err = DispatchLoadOneAction (actionJ, &actions[idx]); + err = DispatchLoadOneAction (controlConfig, actionJ, &actions[idx]); if (err) goto OnErrorExit; } } else { actions = calloc (2, sizeof(DispatchActionT)); - err = DispatchLoadOneAction (actionsJ, &actions[0]); + err = DispatchLoadOneAction (controlConfig, actionsJ, &actions[0]); if (err) goto OnErrorExit; } @@ -165,25 +230,28 @@ STATIC DispatchActionT *DispatchLoadActions (json_object *actionsJ) { STATIC DispatchConfigT *DispatchLoadConfig (const char* filepath) { - json_object *dispatchConfigJ, *ignoreJ; + json_object *controlConfigJ, *ignoreJ; int err; // Load JSON file - dispatchConfigJ= json_object_from_file(filepath); - if (!dispatchConfigJ) goto OnErrorExit; + controlConfigJ= json_object_from_file(filepath); + if (!controlConfigJ) { + 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, *onloadJ=NULL, *controlsJ=NULL, *eventsJ=NULL; - err= wrap_json_unpack(dispatchConfigJ, "{s?o,so,s?o,s?o,s?o !}", "$schema", &ignoreJ, "metadata",&metadataJ, "onload",&onloadJ, "controls",&controlsJ, "events",&eventsJ); + err= wrap_json_unpack(controlConfigJ, "{s?o,so,s?o,s?o,s?o !}", "$schema", &ignoreJ, "metadata",&metadataJ, "onload",&onloadJ, "controls",&controlsJ, "events",&eventsJ); if (err) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG Missing something metadata|[onload]|[controls]|[events] in %s", json_object_get_string(dispatchConfigJ)); + AFB_ERROR ("DISPATCH-LOAD-CONFIG Missing something metadata|[onload]|[controls]|[events] in %s", json_object_get_string(controlConfigJ)); goto OnErrorExit; } - DispatchConfigT *dispatchConfig = calloc (1, sizeof(DispatchConfigT)); + DispatchConfigT *controlConfig = calloc (1, sizeof(DispatchConfigT)); if (metadataJ) { - err= wrap_json_unpack(metadataJ, "{ss,s?s,ss !}", "label", &dispatchConfig->label, "info",&dispatchConfig->info, "version",&dispatchConfig->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)); goto OnErrorExit; @@ -193,19 +261,18 @@ STATIC DispatchConfigT *DispatchLoadConfig (const char* filepath) { if (onloadJ) { json_object * actionsJ; DispatchHandleT *dispatchHandle = calloc (1, sizeof(DispatchHandleT)); - - err= wrap_json_unpack(onloadJ, "{so,s?s,s?s,s?o !}", "label",&dispatchHandle->label, "info",&dispatchHandle->info, "plugin", &dispatchConfig->plugin, "actions",&actionsJ); + err= wrap_json_unpack(onloadJ, "{so,s?s,s?s,s?o !}", "label",&dispatchHandle->label, "info",&dispatchHandle->info, "plugin", &controlConfig->plugin, "actions",&actionsJ); if (err) { AFB_ERROR ("DISPATCH-LOAD-CONFIG:ONLOAD Missing something label|[info]|[plugin]|[actions] in %s", json_object_get_string(onloadJ)); goto OnErrorExit; } - if (dispatchConfig->plugin) { + if (controlConfig->plugin) { // search for default policy config file - json_object *pluginPathJ = ScanForConfig(CONTROL_PLUGIN_PATH , CTL_SCAN_RECURSIVE, dispatchConfig->plugin, NULL); + json_object *pluginPathJ = ScanForConfig(CONTROL_PLUGIN_PATH , CTL_SCAN_RECURSIVE, controlConfig->plugin, NULL); if (!pluginPathJ || json_object_array_length(pluginPathJ) == 0) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:PLUGIN Missing plugin=%s in path=%s", dispatchConfig->plugin, CONTROL_PLUGIN_PATH); + AFB_ERROR ("DISPATCH-LOAD-CONFIG:PLUGIN Missing plugin=%s in path=%s", controlConfig->plugin, CONTROL_PLUGIN_PATH); goto OnErrorExit; } @@ -224,39 +291,67 @@ STATIC DispatchConfigT *DispatchLoadConfig (const char* filepath) { strncpy(pluginpath, fullpath, sizeof(pluginpath)); strncat(pluginpath, "/", sizeof(pluginpath)); strncat(pluginpath, filename, sizeof(pluginpath)); - dispatchConfig->dlHandle = dlopen(pluginpath, RTLD_NOW); - if (!dispatchConfig->dlHandle) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:PLIUGIN Fail to load pluginpath=%s err= %s", pluginpath, dlerror()); + controlConfig->dlHandle = dlopen(pluginpath, RTLD_NOW); + if (!controlConfig->dlHandle) { + AFB_ERROR ("DISPATCH-LOAD-CONFIG:PLUGIN Fail to load pluginpath=%s err= %s", pluginpath, dlerror()); goto OnErrorExit; } - ulong *ctlPluginMagic = (ulong*)dlsym(dispatchConfig->dlHandle, "CtlPluginMagic"); - if (!ctlPluginMagic || *ctlPluginMagic != CTL_PLUGIN_MAGIC) { - AFB_ERROR("DISPATCH-LOAD-CONFIG:PLIUGIN symbol'CtlPluginMagic' missing or != CTL_PLUGIN_MAGIC plugin=%s", pluginpath); + CtlPluginMagicT *ctlPluginMagic = (CtlPluginMagicT*)dlsym(controlConfig->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; + } else { + AFB_NOTICE("DISPATCH-LOAD-CONFIG:Plugin %s successfully registered", ctlPluginMagic->label); } - DispatchPluginInstallCbT ctlPluginInstall = dlsym(dispatchConfig->dlHandle, "CtlPluginOnload"); - if (ctlPluginInstall) { - dispatchConfig->context = (*ctlPluginInstall) (dispatchConfig->label, dispatchConfig->version, dispatchConfig->info); + // Jose hack to make verbosity visible from sharelib + struct afb_binding_data_v2 *afbHidenData = dlsym(controlConfig->dlHandle, "afbBindingV2data"); + if (afbHidenData) *afbHidenData = afbBindingV2data; + + DispatchPluginInstallCbT ctlPluginOnload = dlsym(controlConfig->dlHandle, "CtlPluginOnload"); + if (ctlPluginOnload) { + controlConfig->context = (*ctlPluginOnload) (controlConfig->label, controlConfig->version, controlConfig->info); } } - dispatchHandle->actions= DispatchLoadActions(actionsJ); - dispatchConfig->onload= dispatchHandle; + dispatchHandle->actions= DispatchLoadActions(controlConfig, actionsJ); + if (!dispatchHandle->actions) { + AFB_ERROR ("DISPATCH-LOAD-CONFIG:ONLOAD Error when parsing actions %s", dispatchHandle->label); + goto OnErrorExit; + } + controlConfig->onload= dispatchHandle; + } if (controlsJ) { json_object * actionsJ; - DispatchHandleT *dispatchHandle = calloc (1, sizeof(DispatchHandleT)); - err= wrap_json_unpack(controlsJ, "{so,s?s,so !}", "label",&dispatchHandle->label, "info",&dispatchHandle->info, "actions",&actionsJ); - if (err) { - AFB_ERROR ("DISPATCH-LOAD-CONFIG:CONTROLS Missing something label|[info]|actions in %s", json_object_get_string(controlsJ)); - goto OnErrorExit; + if (json_object_get_type(controlsJ) != json_type_array) { + AFB_ERROR ("DISPATCH-LOAD-CONFIG:CONTROLS invalid JSON array in %s", json_object_get_string(controlsJ)); + goto OnErrorExit; + } + + int length= json_object_array_length(controlsJ); + controlConfig->controls = (DispatchHandleT**) calloc (length+1, sizeof(void*)); + + for (int jdx=0; jdx< length; jdx++) { + DispatchHandleT *dispatchHandle = calloc (1, sizeof(DispatchHandleT)); + json_object *controlJ = json_object_array_get_idx(controlsJ,jdx); + err= wrap_json_unpack(controlJ, "{ss,s?s,so !}", "label",&dispatchHandle->label, "info",&dispatchHandle->info, "actions",&actionsJ); + if (err) { + AFB_ERROR ("DISPATCH-LOAD-CONFIG:CONTROLS Missing something label|[info]|actions in %s", json_object_get_string(controlJ)); + goto OnErrorExit; + } + + dispatchHandle->actions= DispatchLoadActions(controlConfig, actionsJ); + if (!dispatchHandle->actions) { + AFB_ERROR ("DISPATCH-LOAD-CONFIG:CONTROLS Error when parsing actions %s", dispatchHandle->label); + goto OnErrorExit; + } + controlConfig->controls[jdx]= dispatchHandle; } - dispatchHandle->actions= DispatchLoadActions(actionsJ); - dispatchConfig->onload= dispatchHandle; + } if (eventsJ) { @@ -268,11 +363,15 @@ STATIC DispatchConfigT *DispatchLoadConfig (const char* filepath) { AFB_ERROR ("DISPATCH-LOAD-CONFIG:EVENTS Missing something label|[info]|actions in %s", json_object_get_string(eventsJ)); goto OnErrorExit; } - dispatchHandle->actions= DispatchLoadActions(actionsJ); - dispatchConfig->onload= dispatchHandle; + dispatchHandle->actions= DispatchLoadActions(controlConfig, actionsJ); + if (!dispatchHandle->actions) { + AFB_ERROR ("DISPATCH-LOAD-CONFIG:EVENTS Error when parsing actions %s", dispatchHandle->label); + goto OnErrorExit; + } + controlConfig->events= dispatchHandle; } - return dispatchConfig; + return controlConfig; OnErrorExit: return NULL; @@ -301,8 +400,8 @@ PUBLIC int DispatchInit () { strncpy(filepath, fullpath, sizeof(filepath)); strncat(filepath, "/", sizeof(filepath)); strncat(filepath, filename, sizeof(filepath)); - ctlHandle = DispatchLoadConfig (filepath); - if (!ctlHandle) { + configHandle = DispatchLoadConfig (filepath); + if (!configHandle) { AFB_ERROR ("DISPATCH-INIT:ERROR No File to load [%s]", filepath); goto OnErrorExit; } diff --git a/Controler-afb/ctl-lua.c b/Controler-afb/ctl-lua.c index 38a3d5f..71ef8b0 100644 --- a/Controler-afb/ctl-lua.c +++ b/Controler-afb/ctl-lua.c @@ -36,11 +36,6 @@ static lua_State* luaState; -typedef enum { - LUA_DOCALL, - LUA_DOSTRING, - LUA_DOSCRIPT, -} LuaDoActionT; #define CTX_MAGIC 123456789 #define CTX_TOKEN "AFB_ctx" @@ -191,6 +186,7 @@ STATIC int LuaPushArgument (json_object *arg) { lua_pushnumber(luaState, json_object_get_double(arg)); break; default: + AFB_ERROR("LuaPushArgument: unsupported Json object type %s", json_object_get_string(arg)); return 0; } @@ -454,7 +450,56 @@ STATIC int LuaAfbService(lua_State* luaState) { // Generated some fake event based on watchdog/counter -PUBLIC void LuaDoAction (LuaDoActionT action, afb_req request) { +PUBLIC int LuaCallFunc (afb_req request, DispatchActionT *action) { + + int err, count=0; + + json_object* queryJ = afb_req_json(request); + json_object* argsJ = action->argsJ; + const char* func = action->call; + + // load function (should exist in CONTROL_PATH_LUA + lua_getglobal(luaState, func); + + // Push AFB client context on the stack + LuaAfbContextT *afbContext= LuaCtxPush(luaState, request, func); + if (!afbContext) goto OnErrorExit; + + // push argsJ on the stack + if (json_object_get_type(argsJ) != json_type_array) { + count+= LuaPushArgument (argsJ); + } else { + for (int idx=0; idx<json_object_array_length(argsJ); idx++) { + count += LuaPushArgument (json_object_array_get_idx(argsJ, idx)); + } + } + + // push queryJ on the stack + if (json_object_get_type(queryJ) != json_type_array) { + count+= LuaPushArgument (queryJ); + } else { + for (int idx=0; idx<json_object_array_length(queryJ); idx++) { + count += LuaPushArgument (json_object_array_get_idx(queryJ, idx)); + } + } + + // effectively exec LUA code (afb_reply/fail done later from callback) + err=lua_pcall(luaState, count+1, 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; +} + +// Generated some fake event based on watchdog/counter +STATIC void LuaDoAction (LuaDoActionT action, afb_req request) { int err, count=0; @@ -581,8 +626,8 @@ PUBLIC void LuaDoAction (LuaDoActionT action, afb_req request) { 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)); diff --git a/Controler-afb/ctl-plugin-sample.c b/Controler-afb/ctl-plugin-sample.c index f7665f0..ebcaee4 100644 --- a/Controler-afb/ctl-plugin-sample.c +++ b/Controler-afb/ctl-plugin-sample.c @@ -31,19 +31,8 @@ typedef struct { int count; } MyPluginCtxT; -// This tag is mandotory and used as sanity check when loading plugin -PUBLIC ulong CtlPluginMagic=CTL_PLUGIN_MAGIC; - -// Call at initialisation time -PUBLIC void* CtlPluginOnload(char* label, char* version, char* info) { - MyPluginCtxT *pluginCtx= (MyPluginCtxT*)calloc (1, sizeof(MyPluginCtxT)); - pluginCtx->magic = MY_PLUGIN_MAGIC; - pluginCtx->count = 0; - - fprintf(stderr, "*** CONTROLER-PLUGIN-SAMPLE:Install label=%s version=%s info=%s", label, info, version); - AFB_NOTICE ("CONTROLER-PLUGIN-SAMPLE:Install label=%s version=%s info=%s", label, info, version); - return (void*)pluginCtx; -} +// Declare this sharelib as a Controller Plugin +CTL_PLUGIN_REGISTER("MyCtlSamplePlugin"); STATIC const char* jsonToString (json_object *valueJ) { const char *value; @@ -55,18 +44,56 @@ STATIC const char* jsonToString (json_object *valueJ) { return value; } +// Call at initialisation time +PUBLIC void* CtlPluginOnload(char* label, char* version, char* info) { + MyPluginCtxT *pluginCtx= (MyPluginCtxT*)calloc (1, sizeof(MyPluginCtxT)); + pluginCtx->magic = MY_PLUGIN_MAGIC; + pluginCtx->count = -1; -PUBLIC void SamplePolicyCount (afb_req request, DispatchActionT *action, void *context) { - + AFB_NOTICE ("CONTROLER-PLUGIN-SAMPLE:Onload label=%s version=%s info=%s", label, info, version); + return (void*)pluginCtx; +} + +PUBLIC int SamplePolicyInit (afb_req request, DispatchActionT *action, void *context) { + MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context; + + pluginCtx->count = 0; + AFB_NOTICE ("CONTROLER-PLUGIN-SAMPLE:Init label=%s args=%s\n", action->label, jsonToString(action->argsJ)); + return 0; +} + +PUBLIC int sampleControlMultimedia (afb_req request, DispatchActionT *action, void *context) { MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context; if (!context || pluginCtx->magic != MY_PLUGIN_MAGIC) { - AFB_ERROR("CONTROLER-PLUGIN-SAMPLE:count (Hoops) Invalid Sample Plugin Context"); - return; - + AFB_ERROR("CONTROLER-PLUGIN-SAMPLE:sampleControlMultimedia (Hoops) Invalid Sample Plugin Context"); + return -1; }; + pluginCtx->count++; + AFB_NOTICE ("CONTROLER-PLUGIN-SAMPLE:sampleControlMultimedia SamplePolicyCount action=%s args=%s count=%d", action->label, jsonToString(action->argsJ), pluginCtx->count); + return 0; +} + +PUBLIC int sampleControlNavigation (afb_req request, DispatchActionT *action, void *context) { + MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context; + if (!context || pluginCtx->magic != MY_PLUGIN_MAGIC) { + AFB_ERROR("CONTROLER-PLUGIN-SAMPLE:sampleControlNavigation (Hoops) Invalid Sample Plugin Context"); + return -1; + }; pluginCtx->count++; + AFB_NOTICE ("CONTROLER-PLUGIN-SAMPLE:sampleControlNavigation SamplePolicyCount action=%s args=%s count=%d", action->label, jsonToString(action->argsJ), pluginCtx->count); + return 0; +} - AFB_INFO ("CONTROLER-PLUGIN-SAMPLE:Count SamplePolicyCount action=%s args=%s count=%d", action->label, jsonToString(action->argsJ), pluginCtx->count); +PUBLIC int SampleControlEvent (afb_req request, DispatchActionT *action, void *context) { + MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context; + + if (!context || pluginCtx->magic != MY_PLUGIN_MAGIC) { + AFB_ERROR("CONTROLER-PLUGIN-SAMPLE:cousampleControlMultimediant (Hoops) Invalid Sample Plugin Context"); + return -1; + }; + pluginCtx->count++; + AFB_NOTICE ("CONTROLER-PLUGIN-SAMPLE:sampleControlMultimedia SamplePolicyCount action=%s args=%s count=%d", action->label, jsonToString(action->argsJ), pluginCtx->count); + return 0; } diff --git a/conf.d/cmake/config.cmake b/conf.d/cmake/config.cmake index 63c83b8..e70fb62 100644 --- a/conf.d/cmake/config.cmake +++ b/conf.d/cmake/config.cmake @@ -56,7 +56,7 @@ set (gcc_minimal_version 4.9) # PKG_CONFIG required packages # ----------------------------- set (PKG_REQUIRED_LIST - alsa + alsa>=1.1.2 libsystemd>=222 libmicrohttpd>=0.9.55 afb-daemon @@ -71,7 +71,7 @@ set (PKG_REQUIRED_LIST add_compile_options(-DCONTROL_CONFIG_FILE="onload-control-policy.json") add_compile_options(-DCONTROL_CONFIG_PATH="${CMAKE_SOURCE_DIR}/conf.d:${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/config") - add_compile_options(-DCONTROL_LUA_PATH="${CMAKE_SOURCE_DIR}/data:/etc/default/${PROJECT_NAME}/lua:${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/lua") + add_compile_options(-DCONTROL_LUA_PATH="${CMAKE_SOURCE_DIR}/conf.d:/etc/default/${PROJECT_NAME}/lua:${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/lua") set (CTL_PLUGIN_PRE "audio-") diff --git a/conf.d/ctl-rules/onload-control-policy.json b/conf.d/ctl-rules/onload-control-policy.json index 5c0c232..b5d4503 100644 --- a/conf.d/ctl-rules/onload-control-policy.json +++ b/conf.d/ctl-rules/onload-control-policy.json @@ -13,8 +13,11 @@ { "label": "onload-sample-cb", "info": "Call control sharelib install entrypoint", - "callback": "SamplePolicyInstall", - "args": {"arg1" : "first_arg", "nextarg": "second arg value"} + "callback": "SamplePolicyInit", + "args": { + "arg1": "first_arg", + "nextarg": "second arg value" + } }, { "label": "onload-sample-api", "info": "Assert AlsaCore Presence", @@ -30,70 +33,76 @@ ] }, "controls": - [{ + [ + { "label": "multimedia", "actions": [ { "label": "multimedia-control-cb", "info": "Call Sharelib Sample Callback", - "callback": "samplePolicyCB", + "callback": "sampleControlMultimedia", "args": { - "arg1": "snoopy", - "arg2": "toto" + "arg1": "snoopy", + "arg2": "toto" } }, { "label": "multimedia-control-ucm", "info": "Subcall AlSA UCM navigation", "api": "alsacore", - "verb": "ucmset", + "verb": "ping", "args": { - "verb": "multimedia" + "select": "multimedia" } - } - ] - }, - { - "label":"navigation", - "action" : { - "api": "alsacore", - "verb": "ucmset", - "args": { - "verb": "navigation" - }, - "optional": true, - "timeout": 100 - } + }] + }, { + "label": "navigation", + "actions": [ { + "label": "multimedia-control-cb", + "info": "Call Sharelib Sample Callback", + "callback": "sampleControlNavigation", + "args": { + "arg1": "snoopy", + "arg2": "toto" + } + }, { + "label": "navigation-control-ucm", + "api": "alsacore", + "verb": "ping", + "args": { + "select": "navigation" + } + }] }, { - "label":"emergency", - "action": { - "api": "alsacore", - "verb": "ucmset", + "label": "emergency", + "actions": [{ + "label": "emergency-control-ucm", + "api": "alsacore", + "verb": "ping", + "args": { + "select": "emergency" + } + }] + } + ], + "events": + { + "label": "SampleEvent", + "info": "define action when receiving a given event", + "actions": [ + { + "label": "Event Callback-1", + "callback": "SampleControlEvent", "args": { - "verb": "emergency" + "arg": "action-1" + } + }, { + "label": "Event Callback-2", + "callback": "SampleControlEvent", + "args": { + "arg": "action-2" } } - }] - , - "events": [ - { - "label": "SampleEvent", - "comment": "define action when receiving a given event", - "actions": [ - { - "info": "Event Callback-1", - "callback": "ProcessEventCB", - "args": { - "arg": "action-1" - } - }, { - "info": "Event Callback-2", - "callback": "ProcessEventCB", - "args": { - "arg": "action-2" - } - } - ] - } - ] + ] + } } diff --git a/conf.d/ctl-rules/onload-control-script.lua b/conf.d/ctl-rules/onload-control-script.lua index f50bf7a..6cc85fa 100644 --- a/conf.d/ctl-rules/onload-control-script.lua +++ b/conf.d/ctl-rules/onload-control-script.lua @@ -78,8 +78,10 @@ function Test_Binder_Call_Sync () end -function Ping_Test(...) +function Test_Lua_Engine(request, ...) + + AFB:NOTICE ("In est_Lua_Engine"); print ("Ping_Test script arguments:"); for i,v in ipairs(arg) @@ -87,9 +89,8 @@ function Ping_Test(...) print(" -- ", tostring(v)) end - -- push response to client - AFB:success (true, 1234, "ABCD"); - + -- return OK + return 0 end diff --git a/htdocs/audio-control.html b/htdocs/audio-control.html index 3be1ef7..318caba 100644 --- a/htdocs/audio-control.html +++ b/htdocs/audio-control.html @@ -24,7 +24,11 @@ <br> <ol> - + + <li><button onclick="callbinder('control','navigation' ,{'var': 'nav'});">Select Navigation</button></li> + <li><button onclick="callbinder('control','multimedia' ,{'xxx': 'multi'});">Select Mutimedia</button></li> + <li><button onclick="callbinder('control','emergency' ,{'yyy': 'emerg'});">Select Navigation</button></li> + <br> <li><button onclick="callbinder('control','lua_dostring','print(\'Bonjours\'); return true, 4567');">LUA string</button></li> <li><button onclick="callbinder('control','lua_docall' , {'func':'Adjust_Volume_Speed', 'args':[20]});">LUA function</button></li> <li><button onclick="callbinder('control','lua_doscript', {'script':'helloworld-lua-script.lua', args:[{'arg1':'abcd'}, {'next':7890}, {'last':'xyz'}]});">LUA script</button></li> diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml index 225cd8f..b476df7 100644 --- a/nbproject/configurations.xml +++ b/nbproject/configurations.xml @@ -224,7 +224,7 @@ </preprocessorList> </cTool> </item> - <item path="Controler-afb/ctl-plugin-sample.c" ex="false" tool="0" flavor2="2"> + <item path="Controler-afb/ctl-plugin-sample.c" ex="false" tool="0" flavor2="3"> <cTool flags="0"> <incDir> <pElem>build/Controler-afb</pElem> @@ -358,7 +358,7 @@ <preprocessorList> <Elem>CONTROL_CONFIG_FILE="onload-control-policy.json"</Elem> <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/usr/local/audio-bindings/config"</Elem> - <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/data:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> <Elem>CONTROL_MAXPATH_LEN=255</Elem> <Elem>CONTROL_PLUGIN_PATH="/home/fulup/opt/audio-bindings/controler:/usr/lib/audio-bindings"</Elem> <Elem>CTL_PLUGIN_MAGIC=2468013579</Elem> @@ -384,7 +384,7 @@ <preprocessorList> <Elem>CONTROL_CONFIG_FILE="onload-control-policy.json"</Elem> <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/usr/local/audio-bindings/config"</Elem> - <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/data:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> <Elem>CONTROL_MAXPATH_LEN=255</Elem> <Elem>CONTROL_PLUGIN_PATH="/home/fulup/opt/audio-bindings/controler:/usr/lib/audio-bindings"</Elem> <Elem>CTL_PLUGIN_MAGIC=2468013579</Elem> @@ -409,7 +409,7 @@ <preprocessorList> <Elem>CONTROL_CONFIG_FILE="onload-control-policy.json"</Elem> <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/usr/local/audio-bindings/config"</Elem> - <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/data:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> <Elem>CONTROL_MAXPATH_LEN=255</Elem> <Elem>CONTROL_PLUGIN_PATH="/home/fulup/opt/audio-bindings/controler:/usr/lib/audio-bindings"</Elem> <Elem>CTL_PLUGIN_MAGIC=2468013579</Elem> @@ -447,7 +447,7 @@ <preprocessorList> <Elem>CONTROL_CONFIG_FILE="onload-control-policy.json"</Elem> <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/usr/local/audio-bindings/config"</Elem> - <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/data:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> <Elem>CONTROL_MAXPATH_LEN=255</Elem> <Elem>CONTROL_PLUGIN_PATH="/home/fulup/opt/audio-bindings/controler:/usr/lib/audio-bindings"</Elem> <Elem>CTL_PLUGIN_MAGIC=2468013579</Elem> @@ -483,7 +483,7 @@ <preprocessorList> <Elem>CONTROL_CONFIG_FILE="onload-control-policy.json"</Elem> <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/usr/local/audio-bindings/config"</Elem> - <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/data:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> <Elem>CONTROL_MAXPATH_LEN=255</Elem> <Elem>CONTROL_PLUGIN_PATH="/home/fulup/opt/audio-bindings/controler:/usr/lib/audio-bindings"</Elem> <Elem>CTL_PLUGIN_MAGIC=2468013579</Elem> @@ -519,7 +519,7 @@ <preprocessorList> <Elem>CONTROL_CONFIG_FILE="onload-control-policy.json"</Elem> <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/usr/local/audio-bindings/config"</Elem> - <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/data:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> <Elem>CONTROL_MAXPATH_LEN=255</Elem> <Elem>CONTROL_PLUGIN_PATH="/home/fulup/opt/audio-bindings/controler:/usr/lib/audio-bindings"</Elem> <Elem>CTL_PLUGIN_MAGIC=2468013579</Elem> @@ -544,7 +544,7 @@ <preprocessorList> <Elem>CONTROL_CONFIG_FILE="onload-control-policy.json"</Elem> <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/usr/local/audio-bindings/config"</Elem> - <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/data:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> <Elem>CONTROL_MAXPATH_LEN=255</Elem> <Elem>CONTROL_PLUGIN_PATH="/home/fulup/opt/audio-bindings/controler:/usr/lib/audio-bindings"</Elem> <Elem>CTL_PLUGIN_MAGIC=2468013579</Elem> @@ -569,7 +569,7 @@ <preprocessorList> <Elem>CONTROL_CONFIG_FILE="onload-control-policy.json"</Elem> <Elem>CONTROL_CONFIG_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/usr/local/audio-bindings/config"</Elem> - <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/data:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> + <Elem>CONTROL_LUA_PATH="/home/fulup/Workspace/AGL-AppFW/audio-bindings-dev/conf.d:/etc/default/audio-bindings/lua:/usr/local/audio-bindings/lua"</Elem> <Elem>CONTROL_MAXPATH_LEN=255</Elem> <Elem>CONTROL_PLUGIN_PATH="/home/fulup/opt/audio-bindings/controler:/usr/lib/audio-bindings"</Elem> <Elem>CTL_PLUGIN_MAGIC=2468013579</Elem> |