summaryrefslogtreecommitdiffstats
path: root/Controler-afb/ctl-lua.c
diff options
context:
space:
mode:
Diffstat (limited to 'Controler-afb/ctl-lua.c')
-rw-r--r--Controler-afb/ctl-lua.c828
1 files changed, 0 insertions, 828 deletions
diff --git a/Controler-afb/ctl-lua.c b/Controler-afb/ctl-lua.c
deleted file mode 100644
index bf02a31..0000000
--- a/Controler-afb/ctl-lua.c
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
- * Copyright (C) 2016 "IoT.bzh"
- * Author Fulup Ar Foll <fulup@iot.bzh>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ref:
- * http://www.troubleshooters.com/codecorn/lua/lua_c_calls_lua.htm#_Anatomy_of_a_Lua_Call
- * http://acamara.es/blog/2012/08/passing-variables-from-lua-5-2-to-c-and-vice-versa/
- * https://john.nachtimwald.com/2014/07/12/wrapping-a-c-library-in-lua/
- * https://gist.github.com/SONIC3D/10388137
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
-
-#include "ctl-binding.h"
-#include "wrap-json.h"
-
-#define LUA_FIST_ARG 2 // when using luaL_newlib calllback receive libtable as 1st arg
-#define LUA_MSG_MAX_LENGTH 255
-#define JSON_ERROR (json_object*)-1
-
-static lua_State* luaState;
-
-#define CTX_MAGIC 123456789
-#define CTX_TOKEN "AFB_ctx"
-
-typedef struct {
- char *name;
- int count;
- afb_event event;
-} LuaAfbEvent;
-static LuaAfbEvent *luaDefaultEvt;
-
-typedef struct {
- int ctxMagic;
- afb_req request;
- char *info;
-} LuaAfbContextT;
-
-typedef struct {
- const char *callback;
- json_object *context;
-} LuaCallServiceT;
-
-typedef enum {
- AFB_MSG_INFO,
- AFB_MSG_WARNING,
- AFB_MSG_NOTICE,
- AFB_MSG_DEBUG,
- AFB_MSG_ERROR,
-} LuaAfbMessageT;
-
-/*
- * Note(Fulup): I fail to use luaL_setmetatable and replaced it with a simple opaque
- * handle while waiting for someone smarter than me to find a better solution
- * https://stackoverflow.com/questions/45596493/lua-using-lua-newuserdata-from-lua-pcall
- */
-
-STATIC LuaAfbContextT *LuaCtxCheck (lua_State *luaState, int index) {
- LuaAfbContextT *afbContext;
- //luaL_checktype(luaState, index, LUA_TUSERDATA);
- //afbContext = (LuaAfbContextT *)luaL_checkudata(luaState, index, CTX_TOKEN);
- luaL_checktype(luaState, index, LUA_TLIGHTUSERDATA);
- afbContext = (LuaAfbContextT *) lua_touserdata(luaState, index);
- if (afbContext == NULL && afbContext->ctxMagic != CTX_MAGIC) {
- luaL_error(luaState, "Fail to retrieve user data context=%s", CTX_TOKEN);
- AFB_ERROR ("afbContextCheck error retrieving afbContext");
- return NULL;
- }
- return afbContext;
-}
-
-STATIC LuaAfbContextT *LuaCtxPush (lua_State *luaState, afb_req request, const char* info) {
- // LuaAfbContextT *afbContext = (LuaAfbContextT *)lua_newuserdata(luaState, sizeof(LuaAfbContextT));
- // luaL_setmetatable(luaState, CTX_TOKEN);
- LuaAfbContextT *afbContext = (LuaAfbContextT *)calloc(1, sizeof(LuaAfbContextT));
- lua_pushlightuserdata(luaState, afbContext);
- if (!afbContext) {
- AFB_ERROR ("LuaCtxPush fail to allocate user data context");
- return NULL;
- }
- afbContext->ctxMagic=CTX_MAGIC;
- afbContext->info=strdup(info);
- afbContext->request= request;
- return afbContext;
-}
-
-STATIC void LuaCtxFree (LuaAfbContextT *afbContext) {
- free (afbContext->info);
-}
-
-// Push a json structure on the stack as a LUA table
-STATIC int LuaPushArgument (json_object *argsJ) {
-
- //AFB_NOTICE("LuaPushArgument argsJ=%s", json_object_get_string(argsJ));
-
- json_type jtype= json_object_get_type(argsJ);
- switch (jtype) {
- case json_type_object: {
- lua_newtable (luaState);
- json_object_object_foreach (argsJ, key, val) {
- int done = LuaPushArgument (val);
- if (done) {
- lua_setfield(luaState,-2, key);
- }
- }
- break;
- }
- case json_type_array: {
- int length= json_object_array_length(argsJ);
- lua_newtable (luaState);
- for (int idx=0; idx < length; idx ++) {
- json_object *val=json_object_array_get_idx(argsJ, idx);
- LuaPushArgument (val);
- lua_seti (luaState,-2, idx);
- }
- break;
- }
- case json_type_int:
- lua_pushinteger(luaState, json_object_get_int(argsJ));
- break;
- case json_type_string:
- lua_pushstring(luaState, json_object_get_string(argsJ));
- break;
- case json_type_boolean:
- lua_pushboolean(luaState, json_object_get_boolean(argsJ));
- break;
- case json_type_double:
- lua_pushnumber(luaState, json_object_get_double(argsJ));
- break;
- case json_type_null:
- AFB_WARNING("LuaPushArgument: NULL object type %s", json_object_get_string(argsJ));
- return 0;
- break;
-
- default:
- AFB_ERROR("LuaPushArgument: unsupported Json object type %s", json_object_get_string(argsJ));
- return 0;
- }
- return 1;
-}
-
-STATIC json_object *PopOneArg (lua_State* luaState, int idx);
-
-STATIC json_object *LuaTableToJson (lua_State* luaState, int index) {
- int idx;
-
- json_object *tableJ= json_object_new_object();
- const char *key;
- char number[3];
- lua_pushnil(luaState); // 1st key
- for (idx=1; lua_next(luaState, index) != 0; idx++) {
-
- // uses 'key' (at index -2) and 'value' (at index -1)
- if (lua_type(luaState,-2) == LUA_TSTRING) key= lua_tostring(luaState, -2);
- else {
- snprintf(number, sizeof(number),"%d", idx);
- key=number;
- }
- json_object *argJ= PopOneArg(luaState, -1);
- json_object_object_add(tableJ, key, argJ);
- lua_pop(luaState, 1); // removes 'value'; keeps 'key' for next iteration
- }
-
- // Query is empty free empty json object
- if (idx == 1) {
- json_object_put(tableJ);
- return NULL;
- }
- return tableJ;
-}
-
-STATIC json_object *PopOneArg (lua_State* luaState, int idx) {
- json_object *value=NULL;
-
- int luaType = lua_type(luaState, idx);
- switch(luaType) {
- case LUA_TNUMBER: {
- lua_Number number= lua_tonumber(luaState, idx);;
- int nombre = (int)number; // evil trick to determine wether n fits in an integer. (stolen from ltcl.c)
- if (number == nombre) {
- value= json_object_new_int((int)number);
- } else {
- value= json_object_new_double(number);
- }
- break;
- }
- case LUA_TBOOLEAN:
- value= json_object_new_boolean(lua_toboolean(luaState, idx));
- break;
- case LUA_TSTRING:
- value= json_object_new_string(lua_tostring(luaState, idx));
- break;
- case LUA_TTABLE: {
- if (idx > 0) {
- value= LuaTableToJson(luaState, idx);
- } else {
- value= json_object_new_string("UNSUPPORTED_Lua_Nested_Table");
- }
- break;
- }
- case LUA_TNIL:
- value=json_object_new_string("nil") ;
- break;
-
- default:
- AFB_NOTICE ("PopOneArg: script returned Unknown/Unsupported idx=%d type:%d/%s", idx, luaType, lua_typename(luaState, luaType));
- value=NULL;
- }
-
- return value;
-}
-
-static json_object *LuaPopArgs (lua_State* luaState, int start) {
- json_object *responseJ;
-
- int stop = lua_gettop(luaState);
- if(stop-start <0) return NULL;
-
- // start at 2 because we are using a function array lib
- if (start == stop) {
- responseJ=PopOneArg (luaState, start);
- } else {
- // loop on remaining return arguments
- responseJ= json_object_new_array();
- for (int idx=start; idx <= stop; idx++) {
- json_object *argJ=PopOneArg (luaState, idx);
- if (!argJ) goto OnErrorExit;
- json_object_array_add(responseJ, argJ);
- }
- }
-
- return responseJ;
-
- OnErrorExit:
- return NULL;
-}
-
-
-STATIC int LuaFormatMessage(lua_State* luaState, LuaAfbMessageT action) {
- char *message;
-
- json_object *responseJ= LuaPopArgs(luaState, LUA_FIST_ARG);
-
- if (!responseJ) {
- luaL_error(luaState,"LuaFormatMessage empty message");
- goto OnErrorExit;
- }
-
- // if we have only on argument just return the value.
- if (json_object_get_type(responseJ)!=json_type_array || json_object_array_length(responseJ) <2) {
- message= (char*)json_object_get_string(responseJ);
- goto PrintMessage;
- }
-
- // extract format and push all other parameter on the stack
- message = alloca (LUA_MSG_MAX_LENGTH);
- const char *format = json_object_get_string(json_object_array_get_idx(responseJ, 0));
-
- int arrayIdx=1;
- int targetIdx=0;
-
- for (int idx=0; format[idx] !='\0'; idx++) {
-
- if (format[idx]=='%' && format[idx] !='\0') {
- json_object *slotJ= json_object_array_get_idx(responseJ, arrayIdx);
- //if (slotJ) AFB_NOTICE("**** idx=%d slotJ=%s", arrayIdx, json_object_get_string(slotJ));
-
-
- switch (format[++idx]) {
- case 'd':
- if (slotJ) targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"%d", json_object_get_int(slotJ));
- else targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"nil");
- arrayIdx++;
- break;
- case 'f':
- if (slotJ) targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"%f", json_object_get_double(slotJ));
- else targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"nil");
- arrayIdx++;
- break;
-
- case'%':
- message[targetIdx]='%';
- targetIdx++;
- break;
-
- case 's':
- default:
- if (slotJ) targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"%s", json_object_get_string(slotJ));
- else targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"nil");
- arrayIdx++;
- }
-
- } else {
- message[targetIdx++] = format[idx];
- }
- }
- message[targetIdx]='\0';
-
-PrintMessage:
- switch (action) {
- case AFB_MSG_WARNING:
- AFB_WARNING (message);
- break;
- case AFB_MSG_NOTICE:
- AFB_NOTICE (message);
- break;
- case AFB_MSG_DEBUG:
- AFB_DEBUG (message);
- break;
- case AFB_MSG_INFO:
- AFB_INFO (message);
- break;
- case AFB_MSG_ERROR:
- default:
- AFB_ERROR (message);
- }
- return 0; // nothing return to lua
-
- OnErrorExit: // on argument to return (the error message)
- return 1;
-}
-
-STATIC int LuaPrintInfo(lua_State* luaState) {
- int err=LuaFormatMessage (luaState, AFB_MSG_INFO);
- return err;
-}
-
-STATIC int LuaPrintError(lua_State* luaState) {
- int err=LuaFormatMessage (luaState, AFB_MSG_ERROR);
- return err; // no value return
-}
-
-STATIC int LuaPrintWarning(lua_State* luaState) {
- int err=LuaFormatMessage (luaState, AFB_MSG_WARNING);
- return err;
-}
-
-STATIC int LuaPrintNotice(lua_State* luaState) {
- int err=LuaFormatMessage (luaState, AFB_MSG_NOTICE);
- return err;
-}
-
-STATIC int LuaPrintDebug(lua_State* luaState) {
- int err=LuaFormatMessage (luaState, AFB_MSG_DEBUG);
- return err;
-}
-
-STATIC int LuaAfbSuccess(lua_State* luaState) {
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIST_ARG);
- if (!afbContext) goto OnErrorExit;
-
- // ignore context argument
- json_object *responseJ= LuaPopArgs(luaState, LUA_FIST_ARG+1);
- if (responseJ == JSON_ERROR) return 1;
-
- afb_req_success(afbContext->request, responseJ, NULL);
-
- LuaCtxFree(afbContext);
- return 0;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbFail(lua_State* luaState) {
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIST_ARG);
- if (!afbContext) goto OnErrorExit;
-
- json_object *responseJ= LuaPopArgs(luaState, LUA_FIST_ARG+1);
- if (responseJ == JSON_ERROR) return 1;
-
- afb_req_fail(afbContext->request, afbContext->info, json_object_get_string(responseJ));
-
- LuaCtxFree(afbContext);
- return 0;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC void LuaAfbServiceCB(void *handle, int iserror, struct json_object *responseJ) {
- LuaCallServiceT *contextCB= (LuaCallServiceT*)handle;
- int count=1;
-
- lua_getglobal(luaState, contextCB->callback);
-
- // push error status & response
- lua_pushboolean(luaState, iserror);
- count+= LuaPushArgument(responseJ);
- count+= LuaPushArgument(contextCB->context);
-
- int err=lua_pcall(luaState, count, LUA_MULTRET, 0);
- if (err) {
- AFB_ERROR ("LUA-SERICE-CB:FAIL response=%s err=%s", json_object_get_string(responseJ), lua_tostring(luaState,-1) );
- }
-}
-
-
-STATIC int LuaAfbService(lua_State* luaState) {
- int count = lua_gettop(luaState);
-
- // note: argument start at 2 because of AFB: table
- if (count <5 || !lua_isstring(luaState, 2) || !lua_isstring(luaState, 3) || !lua_istable(luaState, 4) || !lua_isstring(luaState, 5)) {
- lua_pushliteral (luaState, "LuaAfbServiceCall-Syntax is AFB:service_call (api, verb, query, callback, handle ....");
- goto OnErrorExit;
- }
-
- // get api/verb+query
- const char *api = lua_tostring(luaState,2);
- const char *verb= lua_tostring(luaState,3);
- json_object *queryJ= LuaTableToJson(luaState, 4);
- if (queryJ == JSON_ERROR) return 1;
-
- LuaCallServiceT *contextCB = calloc (1, sizeof(LuaCallServiceT));
- contextCB->callback= lua_tostring(luaState, 5);
- contextCB->context = LuaPopArgs(luaState, 6);
-
- afb_service_call(api, verb, queryJ, LuaAfbServiceCB, contextCB);
-
- return 0; // no value return
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbServiceSync(lua_State* luaState) {
- int count = lua_gettop(luaState);
- json_object *responseJ;
-
- // note: argument start at 2 because of AFB: table
- if (count <3 || !lua_isstring(luaState, 2) || !lua_isstring(luaState, 3) || !lua_istable(luaState, 4)) {
- lua_pushliteral (luaState, "LuaAfbServiceSync-Syntax is error,data=AFB:service_call (api, verb, query)");
- goto OnErrorExit;
- }
-
- // get api/verb+query
- const char *api = lua_tostring(luaState,2);
- const char *verb= lua_tostring(luaState,3);
- json_object *queryJ= LuaTableToJson(luaState, 4);
-
- int iserror=afb_service_call_sync (api, verb, queryJ, &responseJ);
-
- // push error status & response
- count=1; lua_pushboolean(luaState, iserror);
- count+= LuaPushArgument(responseJ);
-
- return count; // return count values
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbMakeEvent(lua_State* luaState) {
- int count = lua_gettop(luaState);
- LuaAfbEvent *afbevt=calloc(1,sizeof(LuaAfbEvent));
-
- if (count != 1 || !lua_isstring(luaState, 1)) {
- lua_pushliteral (luaState, "LuaAfbMakeEvent-Syntax is evtHandle= AFB:event ('myEventName')");
- goto OnErrorExit;
- }
-
- // event name should be the only argument
- afbevt->name= strdup (lua_tostring(luaState,1));
-
- // create a new binder event
- afbevt->event = afb_daemon_make_event(afbevt->name);
- if (!afb_event_is_valid(afbevt->event)) {
- lua_pushliteral (luaState, "LuaAfbMakeEvent-Fail to Create Binder event");
- goto OnErrorExit;
- }
-
- // push event handler as a LUA opaque handle
- lua_pushlightuserdata(luaState, afbevt);
- return 1;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbPushEvent(lua_State* luaState) {
- LuaAfbEvent *afbevt;
- int index;
-
- // if no private event handle then use default binding event
- if (lua_islightuserdata(luaState, 1)) {
- afbevt = (LuaAfbEvent*) lua_touserdata(luaState, 1);
- index=1;
- } else {
- index=2;
- afbevt=luaDefaultEvt;
- }
-
- if (!lua_isstring(luaState, index)) {
- lua_pushliteral (luaState, "LuaAfbPushEvent-Syntax is AFB:signal ([evtHandle], 'myEventName', 'data-1', ... 'data-n')");
- goto OnErrorExit;
- }
-
- // use every other arguments as event parameters
- index++;
- json_object *ctlEventJ= LuaTableToJson(luaState, index);
-
- int done = afb_event_push(afbevt->event, ctlEventJ);
- if (!done) {
- lua_pushliteral (luaState, "LuaAfbPushEvent-Fail to Push Binder event");
- AFB_ERROR ("LuaAfbPushEvent-Fail to Push Binder event=%s count=%d", afbevt->name, afbevt->count);
- goto OnErrorExit;
- }
- afbevt->count++;
- return 0;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-
-// Generated some fake event based on watchdog/counter
-PUBLIC int LuaCallFunc (DispatchActionT *action, json_object *queryJ) {
-
- int err, count;
-
- json_object* argsJ = action->argsJ;
- const char* func = action->call;
-
- // load function (should exist in CONTROL_PATH_LUA
- lua_getglobal(luaState, func);
-
- // push argsJ on the stack
- count=0;
- if (!argsJ) {
- lua_pushnil(luaState);
- count++;
- } else {
- count+= LuaPushArgument (argsJ);
- }
-
- // push queryJ on the stack
- if (!queryJ) {
- lua_pushnil(luaState);
- count++;
- } else {
- count+= LuaPushArgument (queryJ);
- }
-
- // effectively exec LUA script code
- err=lua_pcall(luaState, count, 1, 0);
- if (err) {
- AFB_ERROR("LuaCallFunc Fail calling %s error=%s", func, lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
-
- // return LUA script value
- int rc= (int)lua_tointeger(luaState, -1);
- return rc;
-
- OnErrorExit:
- return -1;
-}
-
-
-// Execute LUA code from received API request
-STATIC void LuaDoAction (LuaDoActionT action, afb_req request) {
-
- int err, count=0;
- const char *middleName=NULL;
-
- json_object* queryJ = afb_req_json(request);
-
- switch (action) {
-
- case LUA_DOSTRING: {
- const char *script = json_object_get_string(queryJ);
- err=luaL_loadstring(luaState, script);
- if (err) {
- AFB_ERROR ("LUA-DO-COMPILE:FAIL String=%s err=%s", script, lua_tostring(luaState,-1) );
- goto OnErrorExit;
- }
- // Push AFB client context on the stack
- LuaAfbContextT *afbContext= LuaCtxPush(luaState, request, script);
- if (!afbContext) goto OnErrorExit;
-
- break;
- }
-
- case LUA_DOCALL: {
- const char *func;
- json_object *argsJ=NULL;
-
- err= wrap_json_unpack (queryJ, "{s:s, s?o !}", "func", &func, "args", &argsJ);
- if (err) {
- AFB_ERROR ("LUA-DOCALL-SYNTAX missing func|args query=%s", json_object_get_string(queryJ));
- goto OnErrorExit;
- }
-
- // load function (should exist in CONTROL_PATH_LUA
- lua_getglobal(luaState, func);
-
- // Push AFB client context on the stack
- LuaAfbContextT *afbContext= LuaCtxPush(luaState, request, func);
- if (!afbContext) goto OnErrorExit;
-
- // push query on the stack
- if (!argsJ) {
- lua_pushnil(luaState);
- count++;
- } else {
- count+= LuaPushArgument (argsJ);
- }
-
- break;
- }
-
- case LUA_DOSCRIPT: { // Fulup need to fix argument passing
- const char *script;
- char*func;
- char *filename; char*fullpath;
- char luaScriptPath[CONTROL_MAXPATH_LEN];
- json_object *argsJ;
- int index;
-
- // scan luascript search path once
- static json_object *luaScriptPathJ =NULL;
- if (!luaScriptPathJ) luaScriptPathJ= ScanForConfig(CONTROL_LUA_PATH , CTL_SCAN_RECURSIVE, CONTROL_DOSCRIPT_PRE, "lua");
-
- err= wrap_json_unpack (queryJ, "{s:s, s?s s?o s?o !}", "script", &script,"func", &func, "arg", &argsJ);
- if (err) {
- AFB_ERROR ("LUA-DOSCRIPT-SYNTAX:missing script|(args,arg) query=%s", json_object_get_string(queryJ));
- goto OnErrorExit;
- }
-
- // search for filename=script in CONTROL_LUA_PATH
- for (index=0; index < json_object_array_length(luaScriptPathJ); index++) {
- json_object *entryJ=json_object_array_get_idx(luaScriptPathJ, index);
-
- err= wrap_json_unpack (entryJ, "{s:s, s:s !}", "fullpath", &fullpath,"filename", &filename);
- if (err) {
- AFB_ERROR ("LUA-DOSCRIPT-SCAN:HOOPs invalid config file path = %s", json_object_get_string(entryJ));
- goto OnErrorExit;
- }
-
- if (!middleName && !strcmp (filename, script)) {
- middleName= GetMidleName(script);
- strncpy (luaScriptPath, fullpath, sizeof(luaScriptPath));
- strncat (luaScriptPath, "/", sizeof(luaScriptPath));
- strncat (luaScriptPath, filename, sizeof(luaScriptPath));
-
- } else {
- AFB_WARNING("LUA-DOSCRIPT-SCAN:Ignore second script=%s path=%s", filename, fullpath);
- }
- }
-
- // script was loaded we need to parse to make it executable
- err=lua_pcall(luaState, 0, 0, 0);
- if (err) {
- AFB_ERROR ("LUA-DOSCRIPT:FAIL to load %s", luaScriptPath);
- goto OnErrorExit;
- }
-
- // if no func name given try to deduct from filename
- if (!func) func= (char*)GetMidleName(filename);
- if (!func) {
- AFB_ERROR ("LUA-DOSCRIPT:FAIL to deduct funcname from %s", filename);
- goto OnErrorExit;
- }
-
- // load function (should exist in CONTROL_PATH_LUA
- lua_getglobal(luaState, func);
-
- // Push AFB client context on the stack
- LuaAfbContextT *afbContext= LuaCtxPush(luaState, request, func);
- if (!afbContext) goto OnErrorExit;
-
- // push function arguments
- if (!argsJ) {
- lua_pushnil(luaState);
- count++;
- } else {
- count+= LuaPushArgument (argsJ);
- }
-
- break;
- }
-
- default:
- AFB_ERROR ("LUA-DOSCRIPT-ACTION unknown query=%s", json_object_get_string(queryJ));
- goto OnErrorExit;
- }
-
- // effectively exec LUA code (afb_reply/fail done later from callback)
- err=lua_pcall(luaState, count+1, 0, 0);
- if (err) {
- AFB_ERROR ("LUA-DO-EXEC:FAIL query=%s err=%s", json_object_get_string(queryJ), lua_tostring(luaState,-1) );
- goto OnErrorExit;
- }
- return;
-
- OnErrorExit:
- afb_req_fail(request,"LUA:ERROR", lua_tostring(luaState,-1));
- return;
-}
-
-PUBLIC void ctlapi_lua_dostring (afb_req request) {
- LuaDoAction (LUA_DOSTRING, request);
-}
-
-PUBLIC void ctlapi_lua_docall (afb_req request) {
- LuaDoAction (LUA_DOCALL, request);
-}
-
-PUBLIC void ctlapi_lua_doscript (afb_req request) {
- LuaDoAction (LUA_DOSCRIPT, request);
-}
-
-static const luaL_Reg afbFunction[] = {
- {"notice" , LuaPrintNotice},
- {"info" , LuaPrintInfo},
- {"warning", LuaPrintWarning},
- {"debug" , LuaPrintDebug},
- {"error" , LuaPrintError},
- {"callsync", LuaAfbServiceSync},
- {"service", LuaAfbService},
- {"success", LuaAfbSuccess},
- {"fail" , LuaAfbFail},
- {"event" , LuaAfbMakeEvent},
- {"signal" , LuaAfbPushEvent},
-
- {NULL, NULL} /* sentinel */
-};
-
-// Create Binding Event at Init
-PUBLIC int LuaLibInit () {
- int err, index;
-
- // search for default policy config file
- char fullprefix[CONTROL_MAXPATH_LEN];
- strncpy (fullprefix, CONTROL_CONFIG_PRE, sizeof(fullprefix));
- strncat (fullprefix, "-", sizeof(fullprefix));
- strncat (fullprefix, GetBinderName(), sizeof(fullprefix));
- strncat (fullprefix, "-", sizeof(fullprefix));
-
- json_object *luaScriptPathJ = ScanForConfig(CONTROL_LUA_PATH , CTL_SCAN_RECURSIVE, fullprefix, "lua");
-
- // open a new LUA interpretor
- luaState = luaL_newstate();
- if (!luaState) {
- AFB_ERROR ("LUA_INIT: Fail to open lua interpretor");
- goto OnErrorExit;
- }
-
- // load auxiliary libraries
- luaL_openlibs(luaState);
-
- // redirect print to AFB_NOTICE
- luaL_newlib(luaState, afbFunction);
- lua_setglobal(luaState, "AFB");
-
- // create default lua event to send test pause/resume
- luaDefaultEvt=calloc(1,sizeof(LuaAfbEvent));
- luaDefaultEvt->name=CONTROL_LUA_EVENT;
- luaDefaultEvt->event = afb_daemon_make_event(CONTROL_LUA_EVENT);
- if (!afb_event_is_valid(luaDefaultEvt->event)) {
- AFB_ERROR ("POLCTL_INIT: Cannot register lua-events=%s ", CONTROL_LUA_EVENT);
- goto OnErrorExit;;
- }
-
- // load+exec any file found in LUA search path
- for (index=0; index < json_object_array_length(luaScriptPathJ); index++) {
- json_object *entryJ=json_object_array_get_idx(luaScriptPathJ, index);
-
- char *filename; char*fullpath;
- err= wrap_json_unpack (entryJ, "{s:s, s:s !}", "fullpath", &fullpath,"filename", &filename);
- if (err) {
- AFB_ERROR ("LUA-INIT HOOPs invalid config file path = %s", json_object_get_string(entryJ));
- goto OnErrorExit;
- }
-
- char filepath[CONTROL_MAXPATH_LEN];
- strncpy(filepath, fullpath, sizeof(filepath));
- strncat(filepath, "/", sizeof(filepath));
- strncat(filepath, filename, sizeof(filepath));
- err= luaL_loadfile(luaState, filepath);
- if (err) {
- AFB_ERROR ("LUA-LOAD HOOPs Error in LUA loading scripts=%s err=%s", filepath, lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
-
- // exec/compil script
- err = lua_pcall(luaState, 0, 0, 0);
- if (err) {
- AFB_ERROR ("LUA-LOAD HOOPs Error in LUA exec scripts=%s err=%s", filepath, lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
- }
-
- // no policy config found remove control API from binder
- if (index == 0) {
- AFB_WARNING ("POLICY-INIT:WARNING No Control LUA file in path=[%s]", CONTROL_LUA_PATH);
- }
-
- AFB_DEBUG ("Audio control-LUA Init Done");
- return 0;
-
- OnErrorExit:
- return 1;
-}
- \ No newline at end of file