aboutsummaryrefslogtreecommitdiffstats
path: root/Controler-afb
diff options
context:
space:
mode:
Diffstat (limited to 'Controler-afb')
-rw-r--r--Controler-afb/CMakeLists.txt24
-rw-r--r--Controler-afb/ctl-binding.c8
-rw-r--r--Controler-afb/ctl-binding.h80
-rw-r--r--Controler-afb/ctl-dispatch.c318
-rw-r--r--Controler-afb/ctl-events.c16
-rw-r--r--Controler-afb/ctl-lua.c281
-rw-r--r--Controler-afb/ctl-plugin-sample.c64
-rw-r--r--Controler-afb/ctl-policy.c196
8 files changed, 637 insertions, 350 deletions
diff --git a/Controler-afb/CMakeLists.txt b/Controler-afb/CMakeLists.txt
index afebdf2..08bc377 100644
--- a/Controler-afb/CMakeLists.txt
+++ b/Controler-afb/CMakeLists.txt
@@ -33,7 +33,7 @@ endmacro(SET_TARGET_GENSKEL)
PROJECT_TARGET_ADD(control-afb)
# Define project Targets
- ADD_LIBRARY(${TARGET_NAME} MODULE ctl-binding.c ctl-events.c ctl-policy.c ctl-lua.c
+ ADD_LIBRARY(${TARGET_NAME} MODULE ctl-binding.c ctl-events.c ctl-dispatch.c ctl-lua.c
)
# Generate API-v2 hat from OpenAPI json definition
@@ -45,7 +45,6 @@ PROJECT_TARGET_ADD(control-afb)
LABELS "BINDING"
LINK_FLAGS ${BINDINGS_LINK_FLAG}
OUTPUT_NAME ${TARGET_NAME}
-
)
# Library dependencies (include updates automatically)
@@ -56,5 +55,24 @@ PROJECT_TARGET_ADD(control-afb)
# installation directory
INSTALL(TARGETS ${TARGET_NAME}
- LIBRARY DESTINATION ${BINDINGS_INSTALL_DIR})
+ LIBRARY DESTINATION CMAKE_INSTALL_PREFIX )
+
+PROJECT_TARGET_ADD(ctl-plugin-sample)
+
+ # Define targets
+ ADD_LIBRARY(${TARGET_NAME} MODULE ctl-plugin-sample.c)
+
+ # Alsa Plugin properties
+ SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ PREFIX "audio-"
+ OUTPUT_NAME ${TARGET_NAME}
+ )
+ # Library dependencies (include updates automatically)
+ TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ ${link_libraries}
+ )
+
+ # installation directory
+ INSTALL(TARGETS ${TARGET_NAME}
+ LIBRARY DESTINATION ${BINDINGS_INSTALL_DIR}/controler)
diff --git a/Controler-afb/ctl-binding.c b/Controler-afb/ctl-binding.c
index 45c4e1c..fe9388f 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_authorize (CTLAPI_NAVIGATION, request);
+ ctlapi_dispatch (CTLAPI_NAVIGATION, request);
}
PUBLIC void ctlapi_multimedia (afb_req request) {
- ctlapi_authorize (CTLAPI_MULTIMEDIA, request);
+ ctlapi_dispatch (CTLAPI_MULTIMEDIA, request);
}
PUBLIC void ctlapi_emergency (afb_req request) {
- ctlapi_authorize (CTLAPI_EMERGENCY, request);
+ ctlapi_dispatch (CTLAPI_EMERGENCY, request);
}
PUBLIC void ctlapi_monitor (afb_req request) {
@@ -65,7 +65,7 @@ PUBLIC int CtlBindingInit () {
int errcount=0;
errcount += TimerEvtInit();
- errcount += PolicyInit();
+ errcount += DispatchInit();
errcount += LuaLibInit();
AFB_DEBUG ("Audio Policy Control Binding Done errcount=%d", errcount);
diff --git a/Controler-afb/ctl-binding.h b/Controler-afb/ctl-binding.h
index e53d2ca..77d1b6e 100644
--- a/Controler-afb/ctl-binding.h
+++ b/Controler-afb/ctl-binding.h
@@ -14,33 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include <systemd/sd-event.h>
-#include "audio-common.h"
#ifndef CONTROLER_BINDING_INCLUDE
#define CONTROLER_BINDING_INCLUDE
+#define AFB_BINDING_VERSION 2
+#include <afb/afb-binding.h>
+#include <json-c/json.h>
+
+#ifndef PUBLIC
+ #define PUBLIC
+#endif
+#define STATIC static
+
// polctl-binding.c
PUBLIC int CtlBindingInit ();
// ctl-timerevt.c
// ----------------------
-#define DEFAULT_PAUSE_DELAY 3000
-#define DEFAULT_TEST_COUNT 1
-typedef int (*timerCallbackT)(void *context);
-typedef struct {
- int value;
- const char *label;
-} AutoTestCtxT;
-
-typedef struct TimerHandleS {
- int count;
- int delay;
- AutoTestCtxT *context;
- timerCallbackT callback;
- sd_event_source *evtSource;
-} TimerHandleT;
+
PUBLIC int TimerEvtInit (void);
PUBLIC afb_event TimerEvtGet(void);
@@ -49,46 +42,39 @@ PUBLIC void ctlapi_event_test (afb_req request);
// ctl-policy
// -----------
-typedef struct PolicyActionS{
- const char* label;
- const char* api;
- const char* verb;
- json_object *argsJ;
- const char *info;
- int timeout;
- json_object* (*actionCB)(struct PolicyActionS *action,json_object *response, void *context);
-} PolicyActionT;
-
-typedef struct {
- const char* label;
- const char *info;
- const char *version;
- void *context;
-} PolicyHandleT;
-
-typedef struct {
- char *sharelib;
- void *dlHandle;
- PolicyHandleT **handle;
- PolicyActionT **onload;
- PolicyActionT **events;
- PolicyActionT **controls;
-} PolicyCtlConfigT;
-
typedef enum {
CTLAPI_NAVIGATION,
CTLAPI_MULTIMEDIA,
CTLAPI_EMERGENCY,
CTL_NONE=-1
-} PolicyCtlEnumT;
+} DispatchCtlEnumT;
-PUBLIC int PolicyInit(void);
-PUBLIC json_object* ScanForConfig (char* searchPath, char * pre, char *ext);
-PUBLIC void ctlapi_authorize (PolicyCtlEnumT control, afb_req request);
+
+typedef enum {
+ CTL_MODE_NONE=0,
+ CTL_MODE_API,
+ CTL_MODE_CB,
+ CTL_MODE_LUA,
+} CtlRequestModeT;
+
+typedef struct DispatchActionS{
+ const char *info;
+ const char* label;
+ CtlRequestModeT mode;
+ const char* api;
+ const char* call;
+ json_object *argsJ;
+ int timeout;
+ json_object* (*actionCB)(struct DispatchActionS *action,json_object *response, void *context);
+} DispatchActionT;
+
+PUBLIC int DispatchInit(void);
+PUBLIC void ctlapi_dispatch (DispatchCtlEnumT control, afb_req request);
// ctl-lua.c
PUBLIC int LuaLibInit ();
+PUBLIC json_object* ScanForConfig (char* searchPath, char * pre, char *ext);
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
new file mode 100644
index 0000000..cda3431
--- /dev/null
+++ b/Controler-afb/ctl-dispatch.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2016 "IoT.bzh"
+ * Author Fulup Ar Foll <fulup@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, something express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Reference:
+ * Json load using json_unpack https://jansson.readthedocs.io/en/2.9/apiref.html#parsing-and-validating-values
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+
+
+#include <json-c/json_object.h>
+
+#include "wrap-json.h"
+#include "ctl-binding.h"
+
+
+typedef struct {
+ const char* label;
+ const char *info;
+ const char *version;
+ DispatchActionT *actions;
+} DispatchHandleT;
+
+
+typedef struct {
+ const char* label;
+ const char *info;
+ const char *version;
+ char *plugin;
+ void *dlHandle;
+ DispatchHandleT *onload;
+ DispatchHandleT *events;
+ DispatchHandleT *controls;
+} DispatchConfigT;
+
+STATIC DispatchConfigT *ctlHandle = NULL;
+
+PUBLIC void ctlapi_dispatch (DispatchCtlEnumT control, afb_req request) {
+ json_object*tmpJ;
+
+ json_object* argsJ= afb_req_json(request);
+ int done=json_object_object_get_ex(argsJ, "closing", &tmpJ);
+ if (done) return;
+
+}
+
+// List Avaliable Configuration Files
+PUBLIC void ctlapi_config (struct afb_req request) {
+ json_object*tmpJ;
+ char *dirList;
+
+ json_object* argsJ = afb_req_json(request);
+ if (argsJ && json_object_object_get_ex (argsJ, "cfgpath" , &tmpJ)) {
+ dirList = strdup (json_object_get_string(tmpJ));
+ } else {
+ dirList = strdup (CONTROL_DISPATCH_PATH);
+ AFB_NOTICE ("CONFIG-MISSING: use default CONTROL_DISPATCH_PATH=%s", CONTROL_DISPATCH_PATH);
+ }
+
+ // get list of config file
+ struct json_object *responseJ = ScanForConfig(dirList, "onload", "json");
+
+ if (json_object_array_length(responseJ) == 0) {
+ afb_req_fail(request, "CONFIGPATH:EMPTY", "No Config Found in CONTROL_DISPATCH_PATH");
+ } else {
+ afb_req_success(request, responseJ, NULL);
+ }
+
+ return;
+}
+
+// unpack individual action object
+STATIC int DispatchLoadOneAction (json_object *actionJ, DispatchActionT *action) {
+ char *api, *verb, *callback, *lua;
+ 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);
+ 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;
+ }
+
+ if (lua) {
+ action->mode = CTL_MODE_LUA;
+ action->call=lua;
+ modeCount++;
+ }
+
+ if (api && verb) {
+ action->mode = CTL_MODE_API;
+ action->api=api;
+ action->call=verb;
+ modeCount++;
+ }
+
+ if (callback) {
+ action->mode = CTL_MODE_CB;
+ action->call=callback;
+ modeCount++;
+
+ action->actionCB = dlsym(ctlHandle->dlHandle, callback);
+ if (!action->actionCB) {
+ AFB_ERROR ("DISPATCH-LOAD-ACTION fail to find calbback=%s in %s", callback, ctlHandle->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));
+ goto OnErrorExit;
+ }
+
+ if (modeCount > 1) {
+ AFB_ERROR ("DISPATCH-LOAD-ACTION ToMany lua|callback|(api+verb) in %s", json_object_get_string(actionJ));
+ goto OnErrorExit;
+ }
+ return 0;
+
+OnErrorExit:
+ return -1;
+};
+
+STATIC DispatchActionT *DispatchLoadActions (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++) {
+ json_object *actionJ = json_object_array_get_idx(actionsJ, idx);
+ err = DispatchLoadOneAction (actionJ, &actions[idx]);
+ if (err) goto OnErrorExit;
+ }
+
+ } else {
+ actions = calloc (2, sizeof(DispatchActionT));
+ err = DispatchLoadOneAction (actionsJ, &actions[0]);
+ if (err) goto OnErrorExit;
+ }
+
+ return actions;
+
+ OnErrorExit:
+ return NULL;
+
+}
+
+STATIC DispatchConfigT *DispatchLoadConfig (const char* filepath) {
+ json_object *dispatchConfigJ, *ignoreJ;
+ int err;
+
+ // Load JSON file
+ dispatchConfigJ= json_object_from_file(filepath);
+ if (!dispatchConfigJ) 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);
+ if (err) {
+ AFB_ERROR ("DISPATCH-LOAD-CONFIG Missing something metadata|[onload]|[controls]|[events] in %s", json_object_get_string(dispatchConfigJ));
+ goto OnErrorExit;
+ }
+
+ DispatchConfigT *dispatchConfig = calloc (1, sizeof(DispatchConfigT));
+ if (metadataJ) {
+ err= wrap_json_unpack(metadataJ, "{so,s?s,ss !}", "label", &dispatchConfig->label, "info",&dispatchConfig->info, "version",&dispatchConfig->version);
+ if (err) {
+ AFB_ERROR ("DISPATCH-LOAD-CONFIG:METADATA Missing something label|version|[label] in %s", json_object_get_string(metadataJ));
+ goto OnErrorExit;
+ }
+ }
+
+ 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);
+ 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) {
+
+ // search for default policy config file
+ json_object *pluginPathJ = ScanForConfig(CONTROL_PLUGIN_PATH , dispatchConfig->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);
+ goto OnErrorExit;
+ }
+
+ char *filename; char*dirpath;
+ err= wrap_json_unpack (json_object_array_get_idx(pluginPathJ,1), "{s:s, s:s !}", "dirpath", &dirpath,"filename", &filename);
+ if (err) {
+ 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", dirpath, filepath);
+ }
+
+ char filepath[255];
+ strncpy(filepath, dirpath, sizeof(filepath));
+ strncat(filepath, "/", sizeof(filepath));
+ strncat(filepath, filename, sizeof(filepath));
+ dispatchConfig->dlHandle = dlopen(filepath, RTLD_NOW);
+ if (!dispatchConfig->dlHandle) {
+ AFB_ERROR ("DISPATCH-LOAD-CONFIG:PLIUGIN Fail to load filepath=%s err= %s", filepath, dlerror());
+ goto OnErrorExit;
+ }
+ }
+
+ dispatchHandle->actions= DispatchLoadActions(actionsJ);
+ dispatchConfig->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;
+ }
+ dispatchHandle->actions= DispatchLoadActions(actionsJ);
+ dispatchConfig->onload= dispatchHandle;
+ }
+
+ if (eventsJ) {
+ json_object * actionsJ;
+ DispatchHandleT *dispatchHandle = calloc (1, sizeof(DispatchHandleT));
+
+ err= wrap_json_unpack(eventsJ, "{so,s?s,so !}", "label",&dispatchHandle->label, "info",&dispatchHandle->info, "actions",&actionsJ);
+ if (err) {
+ 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;
+ }
+
+ return dispatchConfig;
+
+OnErrorExit:
+ return NULL;
+}
+
+// Load default config file at init
+PUBLIC int DispatchInit () {
+ int index, err;
+
+
+ // search for default dispatch config file
+ json_object* responseJ = ScanForConfig(CONTROL_DISPATCH_PATH, "onload", "json");
+
+ for (index=0; index < json_object_array_length(responseJ); index++) {
+ json_object *entryJ=json_object_array_get_idx(responseJ, index);
+
+ char *filename; char*dirpath;
+ err= wrap_json_unpack (entryJ, "{s:s, s:s !}", "dirpath", &dirpath,"filename", &filename);
+ if (err) {
+ AFB_ERROR ("DISPATCH-INIT HOOPs invalid config file path = %s", json_object_get_string(entryJ));
+ goto OnErrorExit;
+ }
+
+ if (strcasestr(filename, CONTROL_DISPATCH_FILE)) {
+ char filepath[255];
+ strncpy(filepath, dirpath, sizeof(filepath));
+ strncat(filepath, "/", sizeof(filepath));
+ strncat(filepath, filename, sizeof(filepath));
+ ctlHandle = DispatchLoadConfig (filepath);
+ if (!ctlHandle) {
+ AFB_ERROR ("DISPATCH-INIT:ERROR No File to load [%s]", filepath);
+ goto OnErrorExit;
+ }
+ break;
+ }
+ }
+
+ // no dispatch config found remove control API from binder
+ if (index == 0) {
+ AFB_WARNING ("DISPATCH-INIT:WARNING No Control dispatch file [%s]", CONTROL_DISPATCH_FILE);
+ }
+
+ AFB_NOTICE ("DISPATCH-INIT:SUCCES: Audio Control Dispatch Init");
+ return 0;
+
+OnErrorExit:
+ AFB_NOTICE ("DISPATCH-INIT:ERROR: Audio Control Dispatch Init");
+ return 1;
+}
+
+
+
diff --git a/Controler-afb/ctl-events.c b/Controler-afb/ctl-events.c
index f444848..6f710e3 100644
--- a/Controler-afb/ctl-events.c
+++ b/Controler-afb/ctl-events.c
@@ -23,6 +23,22 @@
#include "ctl-binding.h"
+#define DEFAULT_PAUSE_DELAY 3000
+#define DEFAULT_TEST_COUNT 1
+typedef int (*timerCallbackT)(void *context);
+typedef struct {
+ int value;
+ const char *label;
+} AutoTestCtxT;
+
+typedef struct TimerHandleS {
+ int count;
+ int delay;
+ AutoTestCtxT *context;
+ timerCallbackT callback;
+ sd_event_source *evtSource;
+} TimerHandleT;
+
static afb_event afbevt;
STATIC int TimerNext (sd_event_source* source, uint64_t timer, void* handle) {
diff --git a/Controler-afb/ctl-lua.c b/Controler-afb/ctl-lua.c
index 59ffbe8..8b40e38 100644
--- a/Controler-afb/ctl-lua.c
+++ b/Controler-afb/ctl-lua.c
@@ -31,6 +31,8 @@
#include "ctl-binding.h"
#include "wrap-json.h"
+#define LUA_FIRST_ARG 2 // when using luaL_newlib calllback receive libtable as 1st arg
+#define LUA_MSG_MAX_LENGTH 255
static lua_State* luaState;
@@ -55,14 +57,25 @@ typedef struct {
} 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_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");
@@ -72,20 +85,21 @@ STATIC LuaAfbContextT *LuaCtxCheck (lua_State *luaState, int index) {
}
STATIC LuaAfbContextT *LuaCtxPush (lua_State *luaState, afb_req request, const char* info) {
- LuaAfbContextT *afbContext = (LuaAfbContextT *)lua_newuserdata(luaState, sizeof(LuaAfbContextT));
+ // 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;
}
- luaL_setmetatable(luaState, CTX_TOKEN);
afbContext->ctxMagic=CTX_MAGIC;
afbContext->info=strdup(info);
afbContext->request= request;
return afbContext;
}
-STATIC void LuaCtxFree (LuaAfbContextT *afbContext) {
-
+STATIC void LuaCtxFree (LuaAfbContextT *afbContext) {
free (afbContext->info);
}
@@ -95,73 +109,57 @@ PUBLIC json_object* ScanForConfig (char* searchPath, char *pre, char *ext) {
DIR *dirHandle;
char *dirPath;
char* dirList= strdup(searchPath);
- size_t extLen = strlen(ext);
+ size_t extLen=0;
- responseJ = json_object_new_array();
- for (dirPath= strtok(dirList, ":"); dirPath && *dirPath; dirPath=strtok(NULL,":")) {
- struct dirent *dirEnt;
-
+ void ScanDir (char *dirpath) {
+ struct dirent *dirEnt;
dirHandle = opendir (dirPath);
if (!dirHandle) {
AFB_NOTICE ("CONFIG-SCANNING dir=%s not readable", dirPath);
- continue;
+ return;
}
AFB_NOTICE ("CONFIG-SCANNING:ctl_listconfig scanning: %s", dirPath);
while ((dirEnt = readdir(dirHandle)) != NULL) {
+
+ // recursively search embedded directories ignoring any directory starting by '.' or '_'
+ if (dirEnt->d_type == DT_DIR) {
+ char newpath[CONTROL_MAXPATH_LEN];
+ if (dirEnt->d_name[0]=='.' || dirEnt->d_name[0]=='_') continue;
+
+ strncpy(newpath, dirpath, sizeof(newpath));
+ strncat(newpath, "/", sizeof(newpath));
+ strncat(newpath, dirEnt->d_name, sizeof(newpath));
+ }
+
// Unknown type is accepted to support dump filesystems
if (dirEnt->d_type == DT_REG || dirEnt->d_type == DT_UNKNOWN) {
-
+
// check prefix and extention
- size_t extIdx=strlen(dirEnt->d_name) - extLen;
+ size_t extIdx=strlen(dirEnt->d_name)-extLen;
if (extIdx <= 0) continue;
if (pre && !strcasestr (dirEnt->d_name, pre)) continue;
if (ext && strcasecmp (ext, &dirEnt->d_name[extIdx])) continue;
-
+
struct json_object *pathJ = json_object_new_object();
json_object_object_add(pathJ, "dirpath", json_object_new_string(dirPath));
json_object_object_add(pathJ, "filename", json_object_new_string(dirEnt->d_name));
json_object_array_add(responseJ, pathJ);
}
+ closedir(dirHandle);
}
}
-
- free (dirList);
- return (responseJ);
-}
-STATIC int LuaPrintMessage(LuaAfbMessageT action, lua_State* luaState) {
+ if (ext) extLen=strlen(ext);
+ responseJ = json_object_new_array();
- int count = lua_gettop(luaState);
- for (int idx = 1; idx <= count; ++idx) {
- const char *str = lua_tostring(luaState, idx); // Get string
-
- switch (action) {
- case AFB_MSG_NOTICE:
- AFB_NOTICE(str);
- break;
-
- case AFB_MSG_WARNING:
- AFB_WARNING(str);
- break;
-
- default:
- AFB_ERROR(str);
- }
+ // loop recursively on dir
+ for (dirPath= strtok(dirList, ":"); dirPath && *dirPath; dirPath=strtok(NULL,":")) {
+ ScanDir (dirPath);
}
- return 0; // no value return
-}
-
-STATIC int LuaPrintWarning(lua_State* luaState) {
-
- LuaPrintMessage (AFB_MSG_WARNING, luaState);
- return 0; // no value return
-}
-
-STATIC int LuaPrintNotice(lua_State* luaState) {
-
- LuaPrintMessage (AFB_MSG_NOTICE, luaState);
- return 0; // no value return
+
+ free (dirList);
+ return (responseJ);
}
STATIC int LuaPushArgument (json_object *arg) {
@@ -197,9 +195,8 @@ STATIC int LuaPushArgument (json_object *arg) {
return 1;
}
-static json_object *LuaPopArgs (lua_State* luaState, int count);
STATIC json_object *PopOneArg (lua_State* luaState, int idx);
-static json_object *LuaTableToJson (lua_State* luaState, int index) {
+STATIC json_object *LuaTableToJson (lua_State* luaState, int index) {
json_object *tableJ= json_object_new_object();
const char *key;
@@ -207,9 +204,9 @@ static json_object *LuaTableToJson (lua_State* luaState, int index) {
lua_pushnil(luaState); // 1st key
for (int jdx=1; lua_next(luaState, index) != 0; jdx++) {
- printf("jdx=%d %s - %s\n", jdx,
- lua_typename(luaState, lua_type(luaState, -2)),
- lua_typename(luaState, lua_type(luaState, -1)));
+ //printf("jdx=%d %s - %s\n", jdx,
+ //lua_typename(luaState, lua_type(luaState, -2)),
+ //lua_typename(luaState, lua_type(luaState, -1)));
// uses 'key' (at index -2) and 'value' (at index -1)
if (lua_type(luaState,-2) == LUA_TSTRING) key= lua_tostring(luaState, -2);
@@ -228,7 +225,8 @@ static json_object *LuaTableToJson (lua_State* luaState, int index) {
STATIC json_object *PopOneArg (lua_State* luaState, int idx) {
json_object *value=NULL;
- switch(lua_type(luaState, idx)) {
+ int luaType = lua_type(luaState, idx);
+ switch(luaType) {
case LUA_TNUMBER:
value= json_object_new_double(lua_tonumber(luaState, idx));
break;
@@ -239,33 +237,31 @@ STATIC json_object *PopOneArg (lua_State* luaState, int idx) {
value= json_object_new_string(lua_tostring(luaState, idx));
break;
case LUA_TTABLE: {
- AFB_NOTICE ("-++-- idx=%d ", idx);
+ AFB_NOTICE ("-++-- luatable idx=%d ", idx);
value= LuaTableToJson(luaState, idx);
break;
}
default:
- AFB_NOTICE ("script returned Unknown/Unsupported idx=%d type: %s", idx, lua_typename(luaState, idx));
+ AFB_NOTICE ("PopOneArg: script returned Unknown/Unsupported idx=%d type:%d/%s", idx, luaType, lua_typename(luaState, luaType));
value=NULL;
}
- if (value) AFB_NOTICE ("---- idx=%d value=%s", idx, json_object_get_string(value));
return value;
}
-static json_object *LuaPopArgs (lua_State* luaState, int count) {
-
-
+static json_object *LuaPopArgs (lua_State* luaState, int start) {
json_object *responseJ;
- if(count <=0) return NULL;
+ int stop = lua_gettop(luaState);
+ if(stop-start <=0) return NULL;
// start at 2 because we are using a function array lib
- if (count == 2) {
- responseJ=PopOneArg (luaState, 2);
+ if (start == stop) {
+ responseJ=PopOneArg (luaState, start);
} else {
// loop on remaining return arguments
responseJ= json_object_new_array();
- for (int idx=2; idx <= count; idx++) {
+ for (int idx=start; idx <= stop; idx++) {
json_object_array_add(responseJ, PopOneArg (luaState, idx));
}
}
@@ -274,18 +270,104 @@ static json_object *LuaPopArgs (lua_State* luaState, int count) {
}
-STATIC int LuaAfbSuccess(lua_State* luaState) {
+STATIC void LuaFormatMessage(lua_State* luaState, LuaAfbMessageT action) {
+ char *message;
+ json_object *responseJ= LuaPopArgs(luaState, LUA_FIRST_ARG);
+ if (!responseJ) {
+ message="--";
+ goto PrintMessage;
+ }
- int count = lua_gettop(luaState);
+ // 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);
+
+ switch (format[++idx]) {
+ case 'd':
+ targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"%d", json_object_get_int(slotJ));
+ break;
+ case 'f':
+ targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"%f", json_object_get_double(slotJ));
+ break;
+
+ case 's':
+ default:
+ targetIdx += snprintf (&message[targetIdx], LUA_MSG_MAX_LENGTH-targetIdx,"%s", json_object_get_string(slotJ));
+ }
+
+ } else {
+ message[targetIdx++] = format[idx];
+ }
+ }
+
+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);
+ }
+}
+STATIC int LuaPrintInfo(lua_State* luaState) {
+ LuaFormatMessage (luaState, AFB_MSG_INFO);
+ return 0; // no value return
+}
- //AFB_NOTICE ("LuaAfbSuccess args=%s",json_object_get_string(LuaPopArgs(luaState, count)));
-
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, 1);
+STATIC int LuaPrintError(lua_State* luaState) {
+ LuaFormatMessage (luaState, AFB_MSG_ERROR);
+ return 0; // no value return
+}
+
+STATIC int LuaPrintWarning(lua_State* luaState) {
+ LuaFormatMessage (luaState, AFB_MSG_WARNING);
+ return 0; // no value return
+}
+
+STATIC int LuaPrintNotice(lua_State* luaState) {
+ LuaFormatMessage (luaState, AFB_MSG_NOTICE);
+ return 0; // no value return
+}
+
+STATIC int LuaPrintDebug(lua_State* luaState) {
+ LuaFormatMessage (luaState, AFB_MSG_DEBUG);
+ return 0; // no value return
+}
+
+STATIC int LuaAfbSuccess(lua_State* luaState) {
+ LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIRST_ARG);
if (!afbContext) goto OnErrorExit;
+
+ // ignore context argument
+ json_object *responseJ= LuaPopArgs(luaState, LUA_FIRST_ARG+1);
- afb_req_success(afbContext->request, LuaPopArgs(luaState, count), NULL);
+ afb_req_success(afbContext->request, responseJ, NULL);
LuaCtxFree(afbContext);
return 0;
@@ -296,13 +378,12 @@ STATIC int LuaAfbSuccess(lua_State* luaState) {
}
STATIC int LuaAfbFail(lua_State* luaState) {
-
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, 1);
+ LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIRST_ARG);
if (!afbContext) goto OnErrorExit;
- int count = lua_gettop(luaState);
+ json_object *responseJ= LuaPopArgs(luaState, LUA_FIRST_ARG+1);
- afb_req_fail(afbContext->request, afbContext->info, json_object_get_string(LuaPopArgs(luaState, count)));
+ afb_req_fail(afbContext->request, afbContext->info, json_object_get_string(responseJ));
LuaCtxFree(afbContext);
return 0;
@@ -402,15 +483,14 @@ PUBLIC void LuaDoAction (LuaDoActionT action, afb_req request) {
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;
-
- // load function (should exist in CONTROL_PATH_LUA
- lua_getglobal(luaState, func);
-
-
-
+
// push arguments on the stack
if (json_object_get_type(args) != json_type_array) {
count= LuaPushArgument (args);
@@ -420,7 +500,7 @@ PUBLIC void LuaDoAction (LuaDoActionT action, afb_req request) {
if (err) break;
}
}
-
+
break;
}
@@ -431,14 +511,18 @@ PUBLIC void LuaDoAction (LuaDoActionT action, afb_req request) {
// scan luascript search path once
static json_object *luaScriptPathJ =NULL;
- if (!luaScriptPathJ) luaScriptPathJ= ScanForConfig(CONTROL_PATH_LUA , NULL, "lua");
+ if (!luaScriptPathJ) luaScriptPathJ= ScanForConfig(CONTROL_LUA_PATH , NULL, "lua");
err= wrap_json_unpack (queryJ, "{s:s, s?o s?o !}", "script", &script,"args", &args, "arg", &args);
if (err) {
AFB_ERROR ("LUA-DOCALL-SYNTAX missing script|(args,arg) args=%s", json_object_get_string(queryJ));
goto OnErrorExit;
}
-
+
+ // Push AFB client context on the stack
+ LuaAfbContextT *afbContext= LuaCtxPush(luaState, request, script);
+ if (!afbContext) goto OnErrorExit;
+
// push arguments on the stack
if (json_object_get_type(args) != json_type_array) {
lua_createtable(luaState, 1, 0);
@@ -452,9 +536,6 @@ PUBLIC void LuaDoAction (LuaDoActionT action, afb_req request) {
}
}
- LuaAfbContextT *afbContext= LuaCtxPush(luaState, request, script);
- if (!afbContext) goto OnErrorExit;
-
for (index=0; index < json_object_array_length(luaScriptPathJ); index++) {
char *filename; char*dirpath;
json_object *entryJ=json_object_array_get_idx(luaScriptPathJ, index);
@@ -480,10 +561,10 @@ PUBLIC void LuaDoAction (LuaDoActionT action, afb_req request) {
}
if (index == json_object_array_length(luaScriptPathJ)) {
- AFB_ERROR ("LUA-DOSCRIPT HOOPs script=%s not in path=%s", script, CONTROL_PATH_LUA);
+ AFB_ERROR ("LUA-DOSCRIPT HOOPs script=%s not in path=%s", script, CONTROL_LUA_PATH);
goto OnErrorExit;
-
- }
+ }
+
break;
}
@@ -491,10 +572,9 @@ PUBLIC void LuaDoAction (LuaDoActionT action, afb_req request) {
AFB_ERROR ("LUA-DOCALL-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, 0, 0);
+ 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;
@@ -521,7 +601,10 @@ PUBLIC void ctlapi_lua_doscript (afb_req request) {
static const luaL_Reg afbFunction[] = {
{"notice" , LuaPrintNotice},
+ {"info" , LuaPrintInfo},
{"warning", LuaPrintWarning},
+ {"debug" , LuaPrintDebug},
+ {"error" , LuaPrintError},
{"service", LuaAfbService},
{"success", LuaAfbSuccess},
{"fail" , LuaAfbFail},
@@ -533,7 +616,7 @@ PUBLIC int LuaLibInit () {
int err, index;
// search for default policy config file
- json_object *luaScriptPathJ = ScanForConfig(CONTROL_PATH_LUA , "onload", "lua");
+ json_object *luaScriptPathJ = ScanForConfig(CONTROL_LUA_PATH , "onload", "lua");
// open a new LUA interpretor
luaState = luaL_newstate();
@@ -560,7 +643,7 @@ PUBLIC int LuaLibInit () {
goto OnErrorExit;
}
- char filepath[255];
+ char filepath[CONTROL_MAXPATH_LEN];
strncpy(filepath, dirpath, sizeof(filepath));
strncat(filepath, "/", sizeof(filepath));
strncat(filepath, filename, sizeof(filepath));
@@ -575,16 +658,14 @@ PUBLIC int LuaLibInit () {
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_PATH_LUA);
+ AFB_WARNING ("POLICY-INIT:WARNING No Control LUA file in path=[%s]", CONTROL_LUA_PATH);
}
-
-
+
AFB_DEBUG ("Audio control-LUA Init Done");
return 0;
diff --git a/Controler-afb/ctl-plugin-sample.c b/Controler-afb/ctl-plugin-sample.c
new file mode 100644
index 0000000..f232573
--- /dev/null
+++ b/Controler-afb/ctl-plugin-sample.c
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ *
+ * Sample plugin for Controller
+ */
+
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+
+#include "ctl-binding.h"
+
+#define MY_PLUGIN_MAGIC 987654321
+
+typedef struct {
+ int magic;
+ int count;
+} MyPluginCtxT;
+
+STATIC const char* jsonToString (json_object *valueJ) {
+ const char *value;
+ if (valueJ)
+ value=json_object_get_string(valueJ);
+ else
+ value="NULL";
+
+ return value;
+}
+
+PUBLIC int SamplePolicyInstall (DispatchActionT *action, json_object *response, void *context) {
+
+ MyPluginCtxT *pluginCtx= (MyPluginCtxT*)calloc (1, sizeof(MyPluginCtxT));
+ pluginCtx->magic = MY_PLUGIN_MAGIC;
+ pluginCtx->count = 0;
+
+ AFB_INFO ("CONTROLER-PLUGIN-SAMPLE SamplePolicyInstall action=%s args=%s", action->label, jsonToString(action->argsJ));
+
+ return 0;
+}
+
+PUBLIC int SamplePolicyCount (DispatchActionT *action, json_object *response, void *context) {
+
+ MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context;
+ //pluginCtx->magic = MY_PLUGIN_MAGIC;
+ //pluginCtx->count = 0;
+
+ AFB_INFO ("CONTROLER-PLUGIN-SAMPLE SamplePolicyCount action=%s args=%s count=%d", action->label, jsonToString(action->argsJ), pluginCtx->count);
+
+ return 0;
+}
diff --git a/Controler-afb/ctl-policy.c b/Controler-afb/ctl-policy.c
deleted file mode 100644
index 7ad73fa..0000000
--- a/Controler-afb/ctl-policy.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2016 "IoT.bzh"
- * Author Fulup Ar Foll <fulup@iot.bzh>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, something express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-
-#include <json-c/json_object.h>
-
-#include "wrap-json.h"
-#include "ctl-binding.h"
-
-STATIC PolicyCtlConfigT *ctlHandle = NULL;
-
-
-PUBLIC void ctlapi_authorize (PolicyCtlEnumT control, afb_req request) {
- json_object*tmpJ;
-
- json_object* argsJ= afb_req_json(request);
- int done=json_object_object_get_ex(argsJ, "closing", &tmpJ);
- if (done) return;
-
-}
-
-
-// List Avaliable Configuration Files
-PUBLIC void ctlapi_config (struct afb_req request) {
- json_object*tmpJ;
- char *dirList;
-
- json_object* argsJ = afb_req_json(request);
- if (argsJ && json_object_object_get_ex (argsJ, "cfgpath" , &tmpJ)) {
- dirList = strdup (json_object_get_string(tmpJ));
- } else {
- dirList = strdup (CONTROL_PATH_POLICY);
- AFB_NOTICE ("CONFIG-MISSING: use default CONTROL_PATH_POLICY=%s", CONTROL_PATH_POLICY);
- }
-
- // get list of config file
- struct json_object *responseJ = ScanForConfig(dirList, "onload", "json");
-
- if (json_object_array_length(responseJ) == 0) {
- afb_req_fail(request, "CONFIGPATH:EMPTY", "No Config Found in CONTROL_PATH_POLICY");
- } else {
- afb_req_success(request, responseJ, NULL);
- }
-
- return;
-}
-
-STATIC PolicyActionT *PolicyLoadActions (json_object *actionsJ) {
- int err;
- PolicyActionT *actions;
- char *callback; // need to search in DL lib
-
- // unpack individual action object
- int actionUnpack (json_object *actionJ, PolicyActionT *action) {
-
- err= wrap_json_unpack(actionJ, "{ss,s?s,s?o,s?s,s?s,s?s !}"
- , "label",&action->label, "info",&action->info, "callback",&callback, "args",&action->argsJ, "api",&action->api, "verb", &action->verb);
- if (err) {
- AFB_ERROR ("POLICY-LOAD-ACTION Missing something label|info|callback|api|verb|args in %s", json_object_get_string(actionJ));
- return -1;
- }
- if (!callback || !(action->api && action->verb)) {
- AFB_ERROR ("POLICY-LOAD-ACTION Missing something callback|(api+verb) in %s", json_object_get_string(actionJ));
- return -1;
- }
- return 0;
- };
-
- // 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(PolicyActionT));
-
- for (int idx=0; idx < count; idx++) {
- json_object *actionJ = json_object_array_get_idx(actionsJ, idx);
- err = actionUnpack (actionJ, &actions[idx]);
- if (err) goto OnErrorExit;
- }
-
- } else {
- actions = calloc (2, sizeof(PolicyActionT));
- err = actionUnpack (actionsJ, &actions[0]);
- if (err) goto OnErrorExit;
- }
-
- return actions;
-
- OnErrorExit:
- return NULL;
-
-}
-
-// load control policy from file using json_unpack https://jansson.readthedocs.io/en/2.9/apiref.html#parsing-and-validating-values
-STATIC PolicyCtlConfigT *PolicyLoadConfig (const char* filepath) {
- json_object *policyConfigJ, *ignoreJ, *actionsJ;
- PolicyCtlConfigT *policyConfig = calloc (1, sizeof(PolicyCtlConfigT));
- int err;
-
- // Load JSON file
- policyConfigJ= json_object_from_file(filepath);
- if (!policyConfigJ) goto OnErrorExit;
-
- json_object *metadataJ, *onloadJ, *controlsJ, *eventsJ;
- err= wrap_json_unpack(policyConfigJ, "{s?o,so,s?o,so,so !}", "$schema", &ignoreJ, "metadata",&metadataJ, "onload",&onloadJ, "controls",&controlsJ, "events",&eventsJ);
- if (err) {
- AFB_ERROR ("POLICY-LOAD-ERRROR Missing something metadata|onload|controls|events in %s", json_object_get_string(policyConfigJ));
- goto OnErrorExit;
- }
-
- PolicyHandleT *policyHandle = calloc (1, sizeof(PolicyHandleT));
- err= wrap_json_unpack(metadataJ, "{so,s?s,s?s !}", "label", &policyHandle->label, "info",&policyHandle->info, "version",&policyHandle->version);
- if (err) {
- AFB_ERROR ("POLICY-LOAD-CONFIG Missing something label|info|version in %s", json_object_get_string(metadataJ));
- goto OnErrorExit;
- }
-
- if (onloadJ) {
- err= wrap_json_unpack(onloadJ, "{s?o,s?s,s?s !}", "info",&ignoreJ, "label",&ignoreJ, "actions",&actionsJ);
- if (err) {
- AFB_ERROR ("POLICY-LOAD-CONFIG Missing something label|info|plugin|actions in %s", json_object_get_string(metadataJ));
- goto OnErrorExit;
- }
- policyConfig->onload= PolicyLoadActions (actionsJ);
- }
-
- return policyConfig;
-
-OnErrorExit:
- return NULL;
-}
-
-// Load default config file at init
-PUBLIC int PolicyInit () {
- int index, err;
-
-
- // search for default policy config file
- json_object* responseJ = ScanForConfig(CONTROL_PATH_POLICY, "onload", "json");
- return 0;
-
- for (index=0; index < json_object_array_length(responseJ); index++) {
- json_object *entryJ=json_object_array_get_idx(responseJ, index);
-
- char *filename; char*dirpath;
- err= wrap_json_unpack (entryJ, "{s:s, s:s !}", "dirpath", &dirpath,"filename", &filename);
- if (err) {
- AFB_ERROR ("POLICY-INIT HOOPs invalid config file path = %s", json_object_get_string(entryJ));
- goto OnErrorExit;
- }
-
- if (strcasestr(filename, CONTROL_FILE_POLICY)) {
- char filepath[255];
- strncpy(filepath, dirpath, sizeof(filepath));
- strncat(filepath, "/", sizeof(filepath));
- strncat(filepath, filename, sizeof(filepath));
- ctlHandle = PolicyLoadConfig (filepath);
- if (!ctlHandle) {
- AFB_ERROR ("POLICY-INIT:ERROR No File to load [%s]", filepath);
- goto OnErrorExit;
- }
- break;
- }
- }
-
- // no policy config found remove control API from binder
- if (index == 0) {
- AFB_WARNING ("POLICY-INIT:WARNING No Control policy file [%s]", CONTROL_FILE_POLICY);
- }
-
- AFB_NOTICE ("POLICY-INIT:SUCCES: Audio Control Policy Init");
- return 0;
-
-OnErrorExit:
- AFB_NOTICE ("POLICY-INIT:ERROR: Audio Control Policy Init");
- return 1;
-}
-
-
-