aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--Audio-Common/CMakeLists.txt16
-rw-r--r--Audio-Common/audio-common.h4
-rw-r--r--Audio-Common/filescan-utils.c124
-rw-r--r--Audio-Common/filescan-utils.h41
-rw-r--r--Audio-Common/wrap-json.c939
-rw-r--r--Audio-Common/wrap-json.h46
-rw-r--r--Audio-Common/wrap-json.md305
-rw-r--r--Controller-afb/CMakeLists.txt81
-rw-r--r--Controller-afb/README.md344
-rwxr-xr-xController-afb/a.outbin12552 -> 0 bytes
-rw-r--r--Controller-afb/ctl-apidef.h103
-rw-r--r--Controller-afb/ctl-apidef.json228
-rw-r--r--Controller-afb/ctl-binding.c68
-rw-r--r--Controller-afb/ctl-binding.h146
-rw-r--r--Controller-afb/ctl-dispatch.c667
-rw-r--r--Controller-afb/ctl-lua.c1068
-rw-r--r--Controller-afb/ctl-plugin-sample.c134
-rw-r--r--Controller-afb/ctl-policy.c221
-rw-r--r--Controller-afb/ctl-timer.c101
m---------afb-utilities0
-rw-r--r--conf.d/CMakeLists.txt22
-rw-r--r--conf.d/cmake/00-debian-config.cmake1
-rw-r--r--conf.d/cmake/00-fedora-config.cmake1
-rw-r--r--conf.d/cmake/00-suse-config.cmake1
-rw-r--r--conf.d/cmake/config.cmake8
-rw-r--r--conf.d/project/json.d/CMakeLists.txt32
-rw-r--r--conf.d/project/json.d/onload-audio-control.json128
-rw-r--r--conf.d/project/json.d/onload-daemon-standalone.json72
-rw-r--r--conf.d/project/lua.d/CMakeLists.txt32
-rw-r--r--conf.d/project/lua.d/debug-helloworld.lua36
-rw-r--r--conf.d/project/lua.d/onload-aaaa-00-utils.lua86
-rw-r--r--conf.d/project/lua.d/onload-aaaa-01-controls.lua162
-rw-r--r--conf.d/project/lua.d/onload-aaaa-02-timer.lua69
-rw-r--r--conf.d/project/lua.d/onload-aaaa-03-oncall.lua70
-rw-r--r--conf.d/project/lua.d/standalone-sample/onload-daemon-00.lua86
-rw-r--r--conf.d/project/lua.d/standalone-sample/onload-daemon-01.lua57
37 files changed, 13 insertions, 5489 deletions
diff --git a/.gitmodules b/.gitmodules
index b545da1..54b5c1f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
[submodule "conf.d/app-templates"]
path = conf.d/app-templates
url = https://gerrit.automotivelinux.org/gerrit/apps/app-templates
+[submodule "afb-utilities"]
+ path = afb-utilities
+ url = git@github.com:iotbzh/afb-utilities
diff --git a/Audio-Common/CMakeLists.txt b/Audio-Common/CMakeLists.txt
index bd3f344..e50edd2 100644
--- a/Audio-Common/CMakeLists.txt
+++ b/Audio-Common/CMakeLists.txt
@@ -19,8 +19,8 @@
# Add target to project dependency list
PROJECT_TARGET_ADD(audio-common)
- # Define targets
- ADD_LIBRARY(${TARGET_NAME} STATIC audio-common.c wrap-json.c filescan-utils)
+ # Define targets
+ ADD_LIBRARY(${TARGET_NAME} STATIC audio-common.c)
# Library properties
SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
@@ -28,11 +28,11 @@ PROJECT_TARGET_ADD(audio-common)
)
# Library dependencies
- #TARGET_LINK_LIBRARIES(${TARGET_NAME}
- # empty
- #)
-
+ TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ afb-utilities
+ )
+
# Define target includes
- TARGET_INCLUDE_DIRECTORIES(${TARGET_NAME}
+ TARGET_INCLUDE_DIRECTORIES(${TARGET_NAME}
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
-) \ No newline at end of file
+)
diff --git a/Audio-Common/audio-common.h b/Audio-Common/audio-common.h
index 0a68eb3..c61b07f 100644
--- a/Audio-Common/audio-common.h
+++ b/Audio-Common/audio-common.h
@@ -25,8 +25,8 @@
#define AFB_BINDING_VERSION 2
#include <afb/afb-binding.h>
#include <json-c/json.h>
-#include "filescan-utils.h"
-#include "wrap-json.h"
+#include <filescan-utils.h>
+#include <wrap-json.h>
// Waiting for official macro from José
#define AFB_GET_VERBOSITY afb_get_verbosity_v2()
diff --git a/Audio-Common/filescan-utils.c b/Audio-Common/filescan-utils.c
deleted file mode 100644
index 4a5613f..0000000
--- a/Audio-Common/filescan-utils.c
+++ /dev/null
@@ -1,124 +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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <sys/prctl.h>
-#include <dirent.h>
-
-#include "audio-common.h"
-
-
-
-// List Avaliable Configuration Files
-PUBLIC json_object* ScanForConfig (const char* searchPath, CtlScanDirModeT mode, const char *pre, const char *ext) {
- json_object *responseJ;
- char *dirPath;
- char* dirList= strdup(searchPath);
- size_t extLen=0;
-
- void ScanDir (char *searchPath) {
- DIR *dirHandle;
- struct dirent *dirEnt;
- dirHandle = opendir (searchPath);
- if (!dirHandle) {
- AFB_DEBUG ("CONFIG-SCANNING dir=%s not readable", searchPath);
- return;
- }
-
- //AFB_NOTICE ("CONFIG-SCANNING:ctl_listconfig scanning: %s", searchPath);
- while ((dirEnt = readdir(dirHandle)) != NULL) {
-
- // recursively search embedded directories ignoring any directory starting by '.' or '_'
- if (dirEnt->d_type == DT_DIR && mode == CTL_SCAN_RECURSIVE) {
- char newpath[CONTROL_MAXPATH_LEN];
- if (dirEnt->d_name[0]=='.' || dirEnt->d_name[0]=='_') continue;
-
- strncpy(newpath, searchPath, sizeof(newpath));
- strncat(newpath, "/", sizeof(newpath));
- strncat(newpath, dirEnt->d_name, sizeof(newpath));
- ScanDir(newpath);
- continue;
- }
-
- // 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;
- 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, "fullpath", json_object_new_string(searchPath));
- json_object_object_add(pathJ, "filename", json_object_new_string(dirEnt->d_name));
- json_object_array_add(responseJ, pathJ);
- }
- }
- closedir(dirHandle);
- }
-
- if (ext) extLen=strlen(ext);
- responseJ = json_object_new_array();
-
- // loop recursively on dir
- for (dirPath= strtok(dirList, ":"); dirPath && *dirPath; dirPath=strtok(NULL,":")) {
- ScanDir (dirPath);
- }
-
- free (dirList);
- return (responseJ);
-}
-
-PUBLIC const char *GetMidleName(const char*name) {
- char *fullname = strdup(name);
-
- for (int idx = 0; fullname[idx] != '\0'; idx++) {
- int start;
- if (fullname[idx] == '-') {
- start = idx + 1;
- for (int jdx = start; ; jdx++) {
- if (fullname[jdx] == '-' || fullname[jdx] == '.' || fullname[jdx] == '\0') {
- fullname[jdx] = '\0';
- return &fullname[start];
- break;
- }
- }
- break;
- }
- }
- return "";
-}
-
-PUBLIC const char *GetBinderName() {
- char psName[17];
- static char *binderName=NULL;
-
- if (binderName) return binderName;
-
- binderName= getenv("AFB_BINDER_NAME");
- if (!binderName) {
- // retrieve binder name from process name afb-name-trailer
- prctl(PR_GET_NAME, psName,NULL,NULL,NULL);
- binderName=(char*)GetMidleName(psName);
- }
-
- return binderName;
-} \ No newline at end of file
diff --git a/Audio-Common/filescan-utils.h b/Audio-Common/filescan-utils.h
deleted file mode 100644
index cbe15de..0000000
--- a/Audio-Common/filescan-utils.h
+++ /dev/null
@@ -1,41 +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.
- *
- * reference:
- * amixer contents; amixer controls;
- * http://www.tldp.org/HOWTO/Alsa-sound-6.html
- */
-
-#ifndef FILESCAN_UTILS_H
-#define FILESCAN_UTILS_H
-
-#ifndef PUBLIC
- #define PUBLIC
-#endif
-#define STATIC static
-
-// ctl-misc.c
-typedef enum {
- CTL_SCAN_FLAT=0,
- CTL_SCAN_RECURSIVE=1,
-} CtlScanDirModeT;
-
-PUBLIC const char *GetMidleName(const char*name);
-PUBLIC const char *GetBinderName();
-PUBLIC json_object* ScanForConfig (const char* searchPath, CtlScanDirModeT mode, const char *pre, const char *ext);
-
-#endif /* FILESCAN_UTILS_H */
-
diff --git a/Audio-Common/wrap-json.c b/Audio-Common/wrap-json.c
deleted file mode 100644
index 164e127..0000000
--- a/Audio-Common/wrap-json.c
+++ /dev/null
@@ -1,939 +0,0 @@
-/*
- Copyright (C) 2016, 2017 "IoT.bzh"
-
- author: José Bollo <jose.bollo@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.
-*/
-
-#include <string.h>
-
-#include "wrap-json.h"
-
-#define STACKCOUNT 32
-#define STRCOUNT 8
-
-enum {
- wrap_json_error_none,
- wrap_json_error_null_object,
- wrap_json_error_truncated,
- wrap_json_error_internal_error,
- wrap_json_error_out_of_memory,
- wrap_json_error_invalid_character,
- wrap_json_error_too_long,
- wrap_json_error_too_deep,
- wrap_json_error_null_spec,
- wrap_json_error_null_key,
- wrap_json_error_null_string,
- wrap_json_error_out_of_range,
- wrap_json_error_incomplete,
- wrap_json_error_missfit_type,
- wrap_json_error_key_not_found,
- _wrap_json_error_count_
-};
-
-static const char ignore_all[] = " \t\n\r,:";
-static const char pack_accept_arr[] = "][{snbiIfoO";
-static const char pack_accept_key[] = "s}";
-#define pack_accept_any (&pack_accept_arr[1])
-
-static const char unpack_accept_arr[] = "*!][{snbiIfFoO";
-static const char unpack_accept_key[] = "*!s}";
-#define unpack_accept_any (&unpack_accept_arr[3])
-
-static const char *pack_errors[_wrap_json_error_count_] =
-{
- [wrap_json_error_none] = "unknown error",
- [wrap_json_error_null_object] = "null object",
- [wrap_json_error_truncated] = "truncated",
- [wrap_json_error_internal_error] = "internal error",
- [wrap_json_error_out_of_memory] = "out of memory",
- [wrap_json_error_invalid_character] = "invalid character",
- [wrap_json_error_too_long] = "too long",
- [wrap_json_error_too_deep] = "too deep",
- [wrap_json_error_null_spec] = "spec is NULL",
- [wrap_json_error_null_key] = "key is NULL",
- [wrap_json_error_null_string] = "string is NULL",
- [wrap_json_error_out_of_range] = "array too small",
- [wrap_json_error_incomplete] = "incomplete container",
- [wrap_json_error_missfit_type] = "missfit of type",
- [wrap_json_error_key_not_found] = "key not found"
-};
-
-int wrap_json_get_error_position(int rc)
-{
- if (rc < 0)
- rc = -rc;
- return (rc >> 4) + 1;
-}
-
-int wrap_json_get_error_code(int rc)
-{
- if (rc < 0)
- rc = -rc;
- return rc & 15;
-}
-
-const char *wrap_json_get_error_string(int rc)
-{
- rc = wrap_json_get_error_code(rc);
- if (rc >= sizeof pack_errors / sizeof *pack_errors)
- rc = 0;
- return pack_errors[rc];
-}
-
-
-
-static inline const char *skip(const char *d)
-{
- while (*d && strchr(ignore_all, *d))
- d++;
- return d;
-}
-
-int wrap_json_vpack(struct json_object **result, const char *desc, va_list args)
-{
- /* TODO: the case of structs with key being single char should be optimized */
- int nstr, notnull, nullable, rc;
- size_t sz, dsz, ssz;
- char *s;
- char c;
- const char *d;
- char buffer[256];
- struct { const char *str; size_t sz; } strs[STRCOUNT];
- struct { struct json_object *cont, *key; const char *acc; char type; } stack[STACKCOUNT], *top;
- struct json_object *obj;
-
- ssz = sizeof buffer;
- s = buffer;
- top = stack;
- top->key = NULL;
- top->cont = NULL;
- top->acc = pack_accept_any;
- top->type = 0;
- d = desc;
- if (!d)
- goto null_spec;
- d = skip(d);
- for(;;) {
- c = *d;
- if (!c)
- goto truncated;
- if (!strchr(top->acc, c))
- goto invalid_character;
- d = skip(++d);
- switch(c) {
- case 's':
- nullable = 0;
- notnull = 0;
- nstr = 0;
- sz = 0;
- for (;;) {
- strs[nstr].str = va_arg(args, const char*);
- if (strs[nstr].str)
- notnull = 1;
- if (*d == '?') {
- d = skip(++d);
- nullable = 1;
- }
- switch(*d) {
- case '%': strs[nstr].sz = va_arg(args, size_t); d = skip(++d); break;
- case '#': strs[nstr].sz = (size_t)va_arg(args, int); d = skip(++d); break;
- default: strs[nstr].sz = strs[nstr].str ? strlen(strs[nstr].str) : 0; break;
- }
- sz += strs[nstr++].sz;
- if (*d == '?') {
- d = skip(++d);
- nullable = 1;
- }
- if (*d != '+')
- break;
- if (nstr >= STRCOUNT)
- goto too_long;
- d = skip(++d);
- }
- if (*d == '*')
- nullable = 1;
- if (notnull) {
- if (sz > ssz) {
- ssz += ssz;
- if (ssz < sz)
- ssz = sz;
- s = alloca(sz);
- }
- dsz = sz;
- while (nstr) {
- nstr--;
- dsz -= strs[nstr].sz;
- memcpy(&s[dsz], strs[nstr].str, strs[nstr].sz);
- }
- obj = json_object_new_string_len(s, (int)sz);
- if (!obj)
- goto out_of_memory;
- } else if (nullable)
- obj = NULL;
- else
- goto null_string;
- break;
- case 'n':
- obj = NULL;
- break;
- case 'b':
- obj = json_object_new_boolean(va_arg(args, int));
- if (!obj)
- goto out_of_memory;
- break;
- case 'i':
- obj = json_object_new_int(va_arg(args, int));
- if (!obj)
- goto out_of_memory;
- break;
- case 'I':
- obj = json_object_new_int64(va_arg(args, int64_t));
- if (!obj)
- goto out_of_memory;
- break;
- case 'f':
- obj = json_object_new_double(va_arg(args, double));
- if (!obj)
- goto out_of_memory;
- break;
- case 'o':
- case 'O':
- obj = va_arg(args, struct json_object*);
- if (*d == '?')
- d = skip(++d);
- else if (*d != '*' && !obj)
- goto null_object;
- if (c == 'O')
- json_object_get(obj);
- break;
- case '[':
- case '{':
- if (++top >= &stack[STACKCOUNT])
- goto too_deep;
- top->key = NULL;
- if (c == '[') {
- top->type = ']';
- top->acc = pack_accept_arr;
- top->cont = json_object_new_array();
- } else {
- top->type = '}';
- top->acc = pack_accept_key;
- top->cont = json_object_new_object();
- }
- if (!top->cont)
- goto out_of_memory;
- continue;
- case '}':
- case ']':
- if (c != top->type || top <= stack)
- goto internal_error;
- obj = (top--)->cont;
- if (*d == '*' && !(c == '}' ? json_object_object_length(obj) : json_object_array_length(obj))) {
- json_object_put(obj);
- obj = NULL;
- }
- break;
- default:
- goto internal_error;
- }
- switch (top->type) {
- case 0:
- if (top != stack)
- goto internal_error;
- if (*d)
- goto invalid_character;
- *result = obj;
- return 0;
- case ']':
- if (obj || *d != '*')
- json_object_array_add(top->cont, obj);
- if (*d == '*')
- d = skip(++d);
- break;
- case '}':
- if (!obj)
- goto null_key;
- top->key = obj;
- top->acc = pack_accept_any;
- top->type = ':';
- break;
- case ':':
- if (obj || *d != '*')
- json_object_object_add(top->cont, json_object_get_string(top->key), obj);
- if (*d == '*')
- d = skip(++d);
- json_object_put(top->key);
- top->key = NULL;
- top->acc = pack_accept_key;
- top->type = '}';
- break;
- default:
- goto internal_error;
- }
- }
-
-null_object:
- rc = wrap_json_error_null_object;
- goto error;
-truncated:
- rc = wrap_json_error_truncated;
- goto error;
-internal_error:
- rc = wrap_json_error_internal_error;
- goto error;
-out_of_memory:
- rc = wrap_json_error_out_of_memory;
- goto error;
-invalid_character:
- rc = wrap_json_error_invalid_character;
- goto error;
-too_long:
- rc = wrap_json_error_too_long;
- goto error;
-too_deep:
- rc = wrap_json_error_too_deep;
- goto error;
-null_spec:
- rc = wrap_json_error_null_spec;
- goto error;
-null_key:
- rc = wrap_json_error_null_key;
- goto error;
-null_string:
- rc = wrap_json_error_null_string;
- goto error;
-error:
- do {
- json_object_put(top->key);
- json_object_put(top->cont);
- } while (--top >= stack);
- *result = NULL;
- rc = rc | (int)((d - desc) << 4);
- return -rc;
-}
-
-int wrap_json_pack(struct json_object **result, const char *desc, ...)
-{
- int rc;
- va_list args;
-
- va_start(args, desc);
- rc = wrap_json_vpack(result, desc, args);
- va_end(args);
- return rc;
-}
-
-static int vunpack(struct json_object *object, const char *desc, va_list args, int store)
-{
- int rc = 0, optionnal, ignore;
- char c, xacc[2] = { 0, 0 };
- const char *acc;
- const char *d, *fit = NULL;
- const char *key = NULL;
- const char **ps = NULL;
- double *pf = NULL;
- int *pi = NULL;
- int64_t *pI = NULL;
- size_t *pz = NULL;
- struct { struct json_object *parent; const char *acc; int index, count; char type; } stack[STACKCOUNT], *top;
- struct json_object *obj;
- struct json_object **po;
-
- xacc[0] = 0;
- ignore = 0;
- top = NULL;
- acc = unpack_accept_any;
- d = desc;
- if (!d)
- goto null_spec;
- d = skip(d);
- obj = object;
- for(;;) {
- fit = d;
- c = *d;
- if (!c)
- goto truncated;
- if (!strchr(acc, c))
- goto invalid_character;
- d = skip(++d);
- switch(c) {
- case 's':
- if (xacc[0] == '}') {
- /* expects a key */
- key = va_arg(args, const char *);
- if (!key)
- goto null_key;
- if (*d != '?')
- optionnal = 0;
- else {
- optionnal = 1;
- d = skip(++d);
- }
- if (ignore)
- ignore++;
- else {
- if (json_object_object_get_ex(top->parent, key, &obj)) {
- /* found */
- top->index++;
- } else {
- /* not found */
- if (!optionnal)
- goto key_not_found;
- ignore = 1;
- obj = NULL;
- }
- }
- xacc[0] = ':';
- acc = unpack_accept_any;
- continue;
- }
- /* get a string */
- if (store)
- ps = va_arg(args, const char **);
- if (!ignore) {
- if (!json_object_is_type(obj, json_type_string))
- goto missfit;
- if (store && ps)
- *ps = json_object_get_string(obj);
- }
- if (*d == '%') {
- d = skip(++d);
- if (store) {
- pz = va_arg(args, size_t *);
- if (!ignore && pz)
- *pz = (size_t)json_object_get_string_len(obj);
- }
- }
- break;
- case 'n':
- if (!ignore && !json_object_is_type(obj, json_type_null))
- goto missfit;
- break;
- case 'b':
- if (store)
- pi = va_arg(args, int *);
-
- if (!ignore) {
- if (!json_object_is_type(obj, json_type_boolean))
- goto missfit;
- if (store && pi)
- *pi = json_object_get_boolean(obj);
- }
- break;
- case 'i':
- if (store)
- pi = va_arg(args, int *);
-
- if (!ignore) {
- if (!json_object_is_type(obj, json_type_int))
- goto missfit;
- if (store && pi)
- *pi = json_object_get_int(obj);
- }
- break;
- case 'I':
- if (store)
- pI = va_arg(args, int64_t *);
-
- if (!ignore) {
- if (!json_object_is_type(obj, json_type_int))
- goto missfit;
- if (store && pI)
- *pI = json_object_get_int64(obj);
- }
- break;
- case 'f':
- case 'F':
- if (store)
- pf = va_arg(args, double *);
-
- if (!ignore) {
- if (!(json_object_is_type(obj, json_type_double) || (c == 'F' && json_object_is_type(obj, json_type_int))))
- goto missfit;
- if (store && pf)
- *pf = json_object_get_double(obj);
- }
- break;
- case 'o':
- case 'O':
- if (store) {
- po = va_arg(args, struct json_object **);
- if (!ignore && po) {
- if (c == 'O')
- obj = json_object_get(obj);
- *po = obj;
- }
- }
- break;
-
- case '[':
- case '{':
- if (!top)
- top = stack;
- else if (++top >= &stack[STACKCOUNT])
- goto too_deep;
-
- top->acc = acc;
- top->type = xacc[0];
- top->index = 0;
- top->parent = obj;
- if (ignore)
- ignore++;
- if (c == '[') {
- if (!ignore) {
- if (!json_object_is_type(obj, json_type_array))
- goto missfit;
- top->count = json_object_array_length(obj);
- }
- xacc[0] = ']';
- acc = unpack_accept_arr;
- } else {
- if (!ignore) {
- if (!json_object_is_type(obj, json_type_object))
- goto missfit;
- top->count = json_object_object_length(obj);
- }
- xacc[0] = '}';
- acc = unpack_accept_key;
- continue;
- }
- break;
- case '}':
- case ']':
- if (!top || c != xacc[0])
- goto internal_error;
- acc = top->acc;
- xacc[0] = top->type;
- top = top == stack ? NULL : top - 1;
- if (ignore)
- ignore--;
- break;
- case '!':
- if (*d != xacc[0])
- goto invalid_character;
- if (!ignore && top->index != top->count)
- goto incomplete;
- /*@fallthrough@*/
- case '*':
- acc = xacc;
- continue;
- default:
- goto internal_error;
- }
- switch (xacc[0]) {
- case 0:
- if (top)
- goto internal_error;
- if (*d)
- goto invalid_character;
- return 0;
- case ']':
- if (!ignore) {
- key = strchr(unpack_accept_arr, *d);
- if (key && key >= unpack_accept_any) {
- if (top->index >= top->count)
- goto out_of_range;
- obj = json_object_array_get_idx(top->parent, top->index++);
- }
- }
- break;
- case ':':
- acc = unpack_accept_key;
- xacc[0] = '}';
- if (ignore)
- ignore--;
- break;
- default:
- goto internal_error;
- }
- }
-truncated:
- rc = wrap_json_error_truncated;
- goto error;
-internal_error:
- rc = wrap_json_error_internal_error;
- goto error;
-invalid_character:
- rc = wrap_json_error_invalid_character;
- goto error;
-too_deep:
- rc = wrap_json_error_too_deep;
- goto error;
-null_spec:
- rc = wrap_json_error_null_spec;
- goto error;
-null_key:
- rc = wrap_json_error_null_key;
- goto error;
-out_of_range:
- rc = wrap_json_error_out_of_range;
- goto error;
-incomplete:
- rc = wrap_json_error_incomplete;
- goto error;
-missfit:
- rc = wrap_json_error_missfit_type;
- goto errorfit;
-key_not_found:
- rc = wrap_json_error_key_not_found;
- goto error;
-errorfit:
- d = fit;
-error:
- rc = rc | (int)((d - desc) << 4);
- return -rc;
-}
-
-int wrap_json_vcheck(struct json_object *object, const char *desc, va_list args)
-{
- return vunpack(object, desc, args, 0);
-}
-
-int wrap_json_check(struct json_object *object, const char *desc, ...)
-{
- int rc;
- va_list args;
-
- va_start(args, desc);
- rc = vunpack(object, desc, args, 0);
- va_end(args);
- return rc;
-}
-
-int wrap_json_vmatch(struct json_object *object, const char *desc, va_list args)
-{
- return !vunpack(object, desc, args, 0);
-}
-
-int wrap_json_match(struct json_object *object, const char *desc, ...)
-{
- int rc;
- va_list args;
-
- va_start(args, desc);
- rc = vunpack(object, desc, args, 0);
- va_end(args);
- return !rc;
-}
-
-int wrap_json_vunpack(struct json_object *object, const char *desc, va_list args)
-{
- return vunpack(object, desc, args, 1);
-}
-
-int wrap_json_unpack(struct json_object *object, const char *desc, ...)
-{
- int rc;
- va_list args;
-
- va_start(args, desc);
- rc = vunpack(object, desc, args, 1);
- va_end(args);
- return rc;
-}
-
-static void object_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure)
-{
- struct json_object_iterator it = json_object_iter_begin(object);
- struct json_object_iterator end = json_object_iter_end(object);
- while (!json_object_iter_equal(&it, &end)) {
- callback(closure, json_object_iter_peek_value(&it), json_object_iter_peek_name(&it));
- json_object_iter_next(&it);
- }
-}
-
-static void array_for_all(struct json_object *object, void (*callback)(void*,struct json_object*), void *closure)
-{
- int n = json_object_array_length(object);
- int i = 0;
- while(i < n)
- callback(closure, json_object_array_get_idx(object, i++));
-}
-
-void wrap_json_optarray_for_all(struct json_object *object, void (*callback)(void*,struct json_object*), void *closure)
-{
- if (json_object_is_type(object, json_type_array))
- array_for_all(object, callback, closure);
- else
- callback(closure, object);
-}
-
-void wrap_json_array_for_all(struct json_object *object, void (*callback)(void*,struct json_object*), void *closure)
-{
- if (json_object_is_type(object, json_type_array))
- array_for_all(object, callback, closure);
-}
-
-void wrap_json_object_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure)
-{
- if (json_object_is_type(object, json_type_object))
- object_for_all(object, callback, closure);
-}
-
-void wrap_json_optobject_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure)
-{
- if (json_object_is_type(object, json_type_object))
- object_for_all(object, callback, closure);
- else
- callback(closure, object, NULL);
-}
-
-void wrap_json_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure)
-{
- if (!object)
- /* do nothing */;
- else if (json_object_is_type(object, json_type_object))
- object_for_all(object, callback, closure);
- else if (!json_object_is_type(object, json_type_array))
- callback(closure, object, NULL);
- else {
- int n = json_object_array_length(object);
- int i = 0;
- while(i < n)
- callback(closure, json_object_array_get_idx(object, i++), NULL);
- }
-}
-
-#if defined(WRAP_JSON_TEST)
-#include <stdio.h>
-
-void p(const char *desc, ...)
-{
- int rc;
- va_list args;
- struct json_object *result;
-
- va_start(args, desc);
- rc = wrap_json_vpack(&result, desc, args);
- va_end(args);
- if (!rc)
- printf(" SUCCESS %s\n\n", json_object_to_json_string(result));
- else
- printf(" ERROR[char %d err %d] %s\n\n", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc));
- json_object_put(result);
-}
-
-const char *xs[10];
-int *xi[10];
-int64_t *xI[10];
-double *xf[10];
-struct json_object *xo[10];
-size_t xz[10];
-
-void u(const char *value, const char *desc, ...)
-{
- unsigned m, k;
- int rc;
- va_list args;
- struct json_object *obj, *o;
-
- memset(xs, 0, sizeof xs);
- memset(xi, 0, sizeof xi);
- memset(xI, 0, sizeof xI);
- memset(xf, 0, sizeof xf);
- memset(xo, 0, sizeof xo);
- memset(xz, 0, sizeof xz);
- obj = json_tokener_parse(value);
- va_start(args, desc);
- rc = wrap_json_vunpack(obj, desc, args);
- va_end(args);
- if (rc)
- printf(" ERROR[char %d err %d] %s\n\n", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc));
- else {
- value = NULL;
- printf(" SUCCESS");
- va_start(args, desc);
- k = m = 0;
- while(*desc) {
- switch(*desc) {
- case '{': m = (m << 1) | 1; k = 1; break;
- case '}': m = m >> 1; k = m&1; break;
- case '[': m = m << 1; k = 0; break;
- case ']': m = m >> 1; k = m&1; break;
- case 's': printf(" s:%s", k ? va_arg(args, const char*) : *(va_arg(args, const char**)?:&value)); k ^= m&1; break;
- case '%': printf(" %%:%zu", *va_arg(args, size_t*)); k = m&1; break;
- case 'n': printf(" n"); k = m&1; break;
- case 'b': printf(" b:%d", *va_arg(args, int*)); k = m&1; break;
- case 'i': printf(" i:%d", *va_arg(args, int*)); k = m&1; break;
- case 'I': printf(" I:%lld", *va_arg(args, int64_t*)); k = m&1; break;
- case 'f': printf(" f:%f", *va_arg(args, double*)); k = m&1; break;
- case 'F': printf(" F:%f", *va_arg(args, double*)); k = m&1; break;
- case 'o': printf(" o:%s", json_object_to_json_string(*va_arg(args, struct json_object**))); k = m&1; break;
- case 'O': o = *va_arg(args, struct json_object**); printf(" O:%s", json_object_to_json_string(o)); json_object_put(o); k = m&1; break;
- default: break;
- }
- desc++;
- }
- va_end(args);
- printf("\n\n");
- }
- json_object_put(obj);
-}
-
-#define P(...) do{ printf("pack(%s)\n",#__VA_ARGS__); p(__VA_ARGS__); } while(0)
-#define U(...) do{ printf("unpack(%s)\n",#__VA_ARGS__); u(__VA_ARGS__); } while(0)
-
-int main()
-{
- char buffer[4] = {'t', 'e', 's', 't'};
-
- P("n");
- P("b", 1);
- P("b", 0);
- P("i", 1);
- P("I", (uint64_t)0x123456789abcdef);
- P("f", 3.14);
- P("s", "test");
- P("s?", "test");
- P("s?", NULL);
- P("s#", "test asdf", 4);
- P("s%", "test asdf", (size_t)4);
- P("s#", buffer, 4);
- P("s%", buffer, (size_t)4);
- P("s++", "te", "st", "ing");
- P("s#+#+", "test", 1, "test", 2, "test");
- P("s%+%+", "test", (size_t)1, "test", (size_t)2, "test");
- P("{}", 1.0);
- P("[]", 1.0);
- P("o", json_object_new_int(1));
- P("o?", json_object_new_int(1));
- P("o?", NULL);
- P("O", json_object_new_int(1));
- P("O?", json_object_new_int(1));
- P("O?", NULL);
- P("{s:[]}", "foo");
- P("{s+#+: []}", "foo", "barbar", 3, "baz");
- P("{s:s,s:o,s:O}", "a", NULL, "b", NULL, "c", NULL);
- P("{s:**}", "a", NULL);
- P("{s:s*,s:o*,s:O*}", "a", NULL, "b", NULL, "c", NULL);
- P("[i,i,i]", 0, 1, 2);
- P("[s,o,O]", NULL, NULL, NULL);
- P("[**]", NULL);
- P("[s*,o*,O*]", NULL, NULL, NULL);
- P(" s ", "test");
- P("[ ]");
- P("[ i , i, i ] ", 1, 2, 3);
- P("{\n\n1");
- P("[}");
- P("{]");
- P("[");
- P("{");
- P("[i]a", 42);
- P("ia", 42);
- P("s", NULL);
- P("+", NULL);
- P(NULL);
- P("{s:i}", NULL, 1);
- P("{ {}: s }", "foo");
- P("{ s: {}, s:[ii{} }", "foo", "bar", 12, 13);
- P("[[[[[ [[[[[ [[[[ }]]]] ]]]] ]]]]]");
-
- U("true", "b", &xi[0]);
- U("false", "b", &xi[0]);
- U("null", "n");
- U("42", "i", &xi[0]);
- U("123456789", "I", &xI[0]);
- U("3.14", "f", &xf[0]);
- U("12345", "F", &xf[0]);
- U("3.14", "F", &xf[0]);
- U("\"foo\"", "s", &xs[0]);
- U("\"foo\"", "s%", &xs[0], &xz[0]);
- U("{}", "{}");
- U("[]", "[]");
- U("{}", "o", &xo[0]);
- U("{}", "O", &xo[0]);
- U("{\"foo\":42}", "{si}", "foo", &xi[0]);
- U("[1,2,3]", "[i,i,i]", &xi[0], &xi[1], &xi[2]);
- U("{\"a\":1,\"b\":2,\"c\":3}", "{s:i, s:i, s:i}", "a", &xi[0], "b", &xi[1], "c", &xi[2]);
- U("42", "z");
- U("null", "[i]");
- U("[]", "[}");
- U("{}", "{]");
- U("[]", "[");
- U("{}", "{");
- U("[42]", "[i]a", &xi[0]);
- U("42", "ia", &xi[0]);
- U("[]", NULL);
- U("\"foo\"", "s", NULL);
- U("42", "s", NULL);
- U("42", "n");
- U("42", "b", NULL);
- U("42", "f", NULL);
- U("42", "[i]", NULL);
- U("42", "{si}", "foo", NULL);
- U("\"foo\"", "n");
- U("\"foo\"", "b", NULL);
- U("\"foo\"", "i", NULL);
- U("\"foo\"", "I", NULL);
- U("\"foo\"", "f", NULL);
- U("\"foo\"", "F", NULL);
- U("true", "s", NULL);
- U("true", "n");
- U("true", "i", NULL);
- U("true", "I", NULL);
- U("true", "f", NULL);
- U("true", "F", NULL);
- U("[42]", "[ii]", &xi[0], &xi[1]);
- U("{\"foo\":42}", "{si}", NULL, &xi[0]);
- U("{\"foo\":42}", "{si}", "baz", &xi[0]);
- U("[1,2,3]", "[iii!]", &xi[0], &xi[1], &xi[2]);
- U("[1,2,3]", "[ii!]", &xi[0], &xi[1]);
- U("[1,2,3]", "[ii]", &xi[0], &xi[1]);
- U("[1,2,3]", "[ii*]", &xi[0], &xi[1]);
- U("{\"foo\":42,\"baz\":45}", "{sisi}", "baz", &xi[0], "foo", &xi[1]);
- U("{\"foo\":42,\"baz\":45}", "{sisi*}", "baz", &xi[0], "foo", &xi[1]);
- U("{\"foo\":42,\"baz\":45}", "{sisi!}", "baz", &xi[0], "foo", &xi[1]);
- U("{\"foo\":42,\"baz\":45}", "{si}", "baz", &xi[0], "foo", &xi[1]);
- U("{\"foo\":42,\"baz\":45}", "{si*}", "baz", &xi[0], "foo", &xi[1]);
- U("{\"foo\":42,\"baz\":45}", "{si!}", "baz", &xi[0], "foo", &xi[1]);
- U("[1,{\"foo\":2,\"bar\":null},[3,4]]", "[i{sisn}[ii]]", &xi[0], "foo", &xi[1], "bar", &xi[2], &xi[3]);
- U("[1,2,3]", "[ii!i]", &xi[0], &xi[1], &xi[2]);
- U("[1,2,3]", "[ii*i]", &xi[0], &xi[1], &xi[2]);
- U("{\"foo\":1,\"bar\":2}", "{si!si}", "foo", &xi[1], "bar", &xi[2]);
- U("{\"foo\":1,\"bar\":2}", "{si*si}", "foo", &xi[1], "bar", &xi[2]);
- U("{\"foo\":{\"baz\":null,\"bar\":null}}", "{s{sn!}}", "foo", "bar");
- U("[[1,2,3]]", "[[ii!]]", &xi[0], &xi[1]);
- U("{}", "{s?i}", "foo", &xi[0]);
- U("{\"foo\":1}", "{s?i}", "foo", &xi[0]);
- U("{}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]);
- U("{\"foo\":[1,2]}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]);
- U("{\"bar\":{\"baz\":{\"quux\":15}}}", "{s?[ii]s?{s{si!}}}", "foo", &xi[0], &xi[1], "bar", "baz", "quux", &xi[2]);
- U("{\"foo\":{\"bar\":4}}", "{s?{s?i}}", "foo", "bar", &xi[0]);
- U("{\"foo\":{}}", "{s?{s?i}}", "foo", "bar", &xi[0]);
- U("{}", "{s?{s?i}}", "foo", "bar", &xi[0]);
- U("{\"foo\":42,\"baz\":45}", "{s?isi!}", "baz", &xi[0], "foo", &xi[1]);
- U("{\"foo\":42}", "{s?isi!}", "baz", &xi[0], "foo", &xi[1]);
- return 0;
-}
-
-#endif
-
-#if 0
-
-
- /* Unpack the same item twice */
- j = json_pack("{s:s, s:i, s:b}", "foo", "bar", "baz", 42, "quux", 1);
- if(!json_unpack_ex(j, &error, 0, "{s:s,s:s!}", "foo", &s, "foo", &s))
- fail("json_unpack object with strict validation failed");
- {
- const char *possible_errors[] = {
- "2 object item(s) left unpacked: baz, quux",
- "2 object item(s) left unpacked: quux, baz"
- };
- check_errors(possible_errors, 2, "<validation>", 1, 10, 10);
- }
- json_decref(j);
-
-#endif
diff --git a/Audio-Common/wrap-json.h b/Audio-Common/wrap-json.h
deleted file mode 100644
index cb2d0bf..0000000
--- a/Audio-Common/wrap-json.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- Copyright (C) 2016, 2017 "IoT.bzh"
-
- author: José Bollo <jose.bollo@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.
-*/
-
-#pragma once
-
-#include <stdarg.h>
-#include <json-c/json.h>
-
-extern int wrap_json_get_error_position(int rc);
-extern int wrap_json_get_error_code(int rc);
-extern const char *wrap_json_get_error_string(int rc);
-
-extern int wrap_json_vpack(struct json_object **result, const char *desc, va_list args);
-extern int wrap_json_pack(struct json_object **result, const char *desc, ...);
-
-extern int wrap_json_vunpack(struct json_object *object, const char *desc, va_list args);
-extern int wrap_json_unpack(struct json_object *object, const char *desc, ...);
-extern int wrap_json_vcheck(struct json_object *object, const char *desc, va_list args);
-extern int wrap_json_check(struct json_object *object, const char *desc, ...);
-extern int wrap_json_vmatch(struct json_object *object, const char *desc, va_list args);
-extern int wrap_json_match(struct json_object *object, const char *desc, ...);
-
-extern void wrap_json_optarray_for_all(struct json_object *object, void (*callback)(void*,struct json_object*), void *closure);
-extern void wrap_json_array_for_all(struct json_object *object, void (*callback)(void*,struct json_object*), void *closure);
-
-extern void wrap_json_optarray_for_all(struct json_object *object, void (*callback)(void*,struct json_object*), void *closure);
-extern void wrap_json_array_for_all(struct json_object *object, void (*callback)(void*,struct json_object*), void *closure);
-extern void wrap_json_object_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure);
-extern void wrap_json_optobject_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure);
-extern void wrap_json_for_all(struct json_object *object, void (*callback)(void*,struct json_object*,const char*), void *closure);
-
diff --git a/Audio-Common/wrap-json.md b/Audio-Common/wrap-json.md
deleted file mode 100644
index 92940f1..0000000
--- a/Audio-Common/wrap-json.md
+++ /dev/null
@@ -1,305 +0,0 @@
-WRAP-JSON facility
-==================
-
-The facility wrap-json is based on the pack/unpack API on the
-libray jansson. The two chapters below are copied from the
-documentation of jansson library copyrighted by Petri Lehtinen
-(see at end).
-
-Building Values
----------------
-
-This section describes functions that help to create, or *pack*, complex
-JSON values, especially nested objects and arrays. Value building is
-based on a *format string* that is used to tell the functions about the
-expected arguments.
-
-For example, the format string `"i"` specifies a single integer value,
-while the format string `"[ssb]"` or the equivalent `"[s, s, b]"`
-specifies an array value with two strings and a boolean as its items:
-
- /* Create the JSON integer 42 */
- wrap_json_pack(&result, "i", 42);
-
- /* Create the JSON array ["foo", "bar", true] */
- wrap_json_pack(&result, "[ssb]", "foo", "bar", 1);
-
-Here's the full list of format specifiers. The type in parentheses
-denotes the resulting JSON type, and the type in brackets (if any)
-denotes the C type that is expected as the corresponding argument or
-arguments.
-
-`s` (string) \[const char \*\]
-
-: Convert a null terminated UTF-8 string to a JSON string.
-
-`s?` (string) \[const char \*\]
-
-: Like `s`, but if the argument is *NULL*, output a JSON null value.
-
-`s*` (string) \[const char \*\]
-
-: Like `s`, but if the argument is *NULL*, do not output any value.
- This format can only be used inside an object or an array. If used
- inside an object, the corresponding key is additionally suppressed
- when the value is omitted. See below for an example.
-
-`s#` (string) \[const char \*, int\]
-
-: Convert a UTF-8 buffer of a given length to a JSON string.
-
-`s%` (string) \[const char \*, size\_t\]
-
-: Like `s#` but the length argument is of type size\_t.
-
-`+` \[const char \*\]
-
-: Like `s`, but concatenate to the previous string. Only valid after
- `s`, `s#`, `+` or `+#`.
-
-`+#` \[const char \*, int\]
-
-: Like `s#`, but concatenate to the previous string. Only valid after
- `s`, `s#`, `+` or `+#`.
-
-`+%` (string) \[const char \*, size\_t\]
-
-: Like `+#` but the length argument is of type size\_t.
-
-`n` (null)
-
-: Output a JSON null value. No argument is consumed.
-
-`b` (boolean) \[int\]
-
-: Convert a C int to JSON boolean value. Zero is converted to `false`
- and non-zero to `true`.
-
-`i` (integer) \[int\]
-
-: Convert a C int to JSON integer.
-
-`I` (integer) \[json\_int\_t\]
-
-: Convert a C json\_int\_t to JSON integer.
-
-`f` (real) \[double\]
-
-: Convert a C double to JSON real.
-
-`o` (any value) \[json\_t \*\]
-
-: Output any given JSON value as-is. If the value is added to an array
- or object, the reference to the value passed to `o` is stolen by the
- container.
-
-`O` (any value) \[json\_t \*\]
-
-: Like `o`, but the argument's reference count is incremented. This is
- useful if you pack into an array or object and want to keep the
- reference for the JSON value consumed by `O` to yourself.
-
-`o?`, `O?` (any value) \[json\_t \*\]
-
-: Like `o` and `O`, respectively, but if the argument is *NULL*,
- output a JSON null value.
-
-`o*`, `O*` (any value) \[json\_t \*\]
-
-: Like `o` and `O`, respectively, but if the argument is *NULL*, do
- not output any value. This format can only be used inside an object
- or an array. If used inside an object, the corresponding key is
- additionally suppressed. See below for an example.
-
-`[fmt]` (array)
-
-: Build an array with contents from the inner format string. `fmt` may
- contain objects and arrays, i.e. recursive value building is
- supported.
-
-`{fmt}` (object)
-
-: Build an object with contents from the inner format string `fmt`.
- The first, third, etc. format specifier represent a key, and must be
- a string (see `s`, `s#`, `+` and `+#` above), as object keys are
- always strings. The second, fourth, etc. format specifier represent
- a value. Any value may be an object or array, i.e. recursive value
- building is supported.
-
-Whitespace, `:` and `,` are ignored.
-
-More examples:
-
- /* Build an empty JSON object */
- wrap_json_pack(&result, "{}");
-
- /* Build the JSON object {"foo": 42, "bar": 7} */
- wrap_json_pack(&result, "{sisi}", "foo", 42, "bar", 7);
-
- /* Like above, ':', ',' and whitespace are ignored */
- wrap_json_pack(&result, "{s:i, s:i}", "foo", 42, "bar", 7);
-
- /* Build the JSON array [[1, 2], {"cool": true}] */
- wrap_json_pack(&result, "[[i,i],{s:b}]", 1, 2, "cool", 1);
-
- /* Build a string from a non-null terminated buffer */
- char buffer[4] = {'t', 'e', 's', 't'};
- wrap_json_pack(&result, "s#", buffer, 4);
-
- /* Concatenate strings together to build the JSON string "foobarbaz" */
- wrap_json_pack(&result, "s++", "foo", "bar", "baz");
-
- /* Create an empty object or array when optional members are missing */
- wrap_json_pack(&result, "{s:s*,s:o*,s:O*}", "foo", NULL, "bar", NULL, "baz", NULL);
- wrap_json_pack(&result, "[s*,o*,O*]", NULL, NULL, NULL);
-
-Parsing and Validating Values
------------------------------
-
-This section describes functions that help to validate complex values
-and extract, or *unpack*, data from them. Like building values
-&lt;apiref-pack&gt;, this is also based on format strings.
-
-While a JSON value is unpacked, the type specified in the format string
-is checked to match that of the JSON value. This is the validation part
-of the process. In addition to this, the unpacking functions can also
-check that all items of arrays and objects are unpacked. This check be
-enabled with the format specifier `!` or by using the flag
-`JSON_STRICT`. See below for details.
-
-Here's the full list of format specifiers. The type in parentheses
-denotes the JSON type, and the type in brackets (if any) denotes the C
-type whose address should be passed.
-
-`s` (string) \[const char \*\]
-
-: Convert a JSON string to a pointer to a null terminated UTF-8
- string. The resulting string is extracted by using
- json\_string\_value() internally, so it exists as long as there are
- still references to the corresponding JSON string.
-
-`s%` (string) \[const char \*, size\_t \*\]
-
-: Convert a JSON string to a pointer to a null terminated UTF-8 string
- and its length.
-
-`n` (null)
-
-: Expect a JSON null value. Nothing is extracted.
-
-`b` (boolean) \[int\]
-
-: Convert a JSON boolean value to a C int, so that `true` is converted
- to 1 and `false` to 0.
-
-`i` (integer) \[int\]
-
-: Convert a JSON integer to C int.
-
-`I` (integer) \[json\_int\_t\]
-
-: Convert a JSON integer to C json\_int\_t.
-
-`f` (real) \[double\]
-
-: Convert a JSON real to C double.
-
-`F` (integer or real) \[double\]
-
-: Convert a JSON number (integer or real) to C double.
-
-`o` (any value) \[json\_t \*\]
-
-: Store a JSON value with no conversion to a json\_t pointer.
-
-`O` (any value) \[json\_t \*\]
-
-: Like `O`, but the JSON value's reference count is incremented.
-
-`[fmt]` (array)
-
-: Convert each item in the JSON array according to the inner format
- string. `fmt` may contain objects and arrays, i.e. recursive value
- extraction is supported.
-
-`{fmt}` (object)
-
-: Convert each item in the JSON object according to the inner format
- string `fmt`. The first, third, etc. format specifier represent a
- key, and must be `s`. The corresponding argument to unpack functions
- is read as the object key. The second fourth, etc. format specifier
- represent a value and is written to the address given as the
- corresponding argument. **Note** that every other argument is read
- from and every other is written to.
-
- `fmt` may contain objects and arrays as values, i.e. recursive value
- extraction is supported.
-
-`!`
-
-: This special format specifier is used to enable the check that all
- object and array items are accessed, on a per-value basis. It must
- appear inside an array or object as the last format specifier before
- the closing bracket or brace.
-
-`*`
-
-: This special format specifier is the opposite of `!`. This is the default.
- It must appear inside an array or object as the last format specifier
- before the closing bracket or brace.
-
-Whitespace, `:` and `,` are ignored.
-
-Examples:
-
- /* root is the JSON integer 42 */
- int myint;
- wrap_json_unpack(root, "i", &myint);
- assert(myint == 42);
-
- /* root is the JSON object {"foo": "bar", "quux": true} */
- const char *str;
- int boolean;
- wrap_json_unpack(root, "{s:s, s:b}", "foo", &str, "quux", &boolean);
- assert(strcmp(str, "bar") == 0 && boolean == 1);
-
- /* root is the JSON array [[1, 2], {"baz": null} */
- wrap_json_check(root, "[[i,i], {s:n}]", "baz");
- /* returns 0 for validation success, nothing is extracted */
-
- /* root is the JSON array [1, 2, 3, 4, 5] */
- int myint1, myint2;
- wrap_json_unpack(root, "[ii!]", &myint1, &myint2);
- /* returns -1 for failed validation */
-
- /* root is an empty JSON object */
- int myint = 0, myint2 = 0, myint3 = 0;
- wrap_json_unpack(root, "{s?i, s?[ii]}",
- "foo", &myint1,
- "bar", &myint2, &myint3);
- /* myint1, myint2 or myint3 is no touched as "foo" and "bar" don't exist */
-
-
-Copyright
----------
-
-Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/Controller-afb/CMakeLists.txt b/Controller-afb/CMakeLists.txt
deleted file mode 100644
index 9d27947..0000000
--- a/Controller-afb/CMakeLists.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-###########################################################################
-# Copyright 2015, 2016, 2017 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.
-###########################################################################
-
-ADD_COMPILE_OPTIONS(-DCONTROL_ONLOAD_PROFILE="onload-default-profile")
-
-ADD_COMPILE_OPTIONS(-DCONTROL_DOSCRIPT_PRE="debug")
-ADD_COMPILE_OPTIONS(-DCONTROL_CONFIG_PRE="onload")
-ADD_COMPILE_OPTIONS(-DCONTROL_CONFIG_POST="control")
-ADD_COMPILE_OPTIONS(-DCONTROL_CONFIG_PATH="${CMAKE_SOURCE_DIR}/conf.d/project/config.d:${CMAKE_INSTALL_PREFIX}/controller/config.d")
-ADD_COMPILE_OPTIONS(-DCTL_PLUGIN_MAGIC=2468013579)
-ADD_COMPILE_OPTIONS(-DCONTROL_PLUGIN_PATH="${CMAKE_BINARY_DIR}:${CMAKE_INSTALL_PREFIX}/controller-plugins:/usr/lib/afb/controller-plugins/ctlplug")
-
-# Include LUA only when requested
-if(CONTROL_SUPPORT_LUA)
- message(STATUS "Notice: LUA Controler Support Selected")
- set(CTL_LUA_SOURCE ctl-lua.c)
- ADD_COMPILE_OPTIONS(-DCONTROL_SUPPORT_LUA)
- ADD_COMPILE_OPTIONS(-DCONTROL_LUA_EVENT="luaevt")
- ADD_COMPILE_OPTIONS(-DCONTROL_LUA_PATH="${CMAKE_SOURCE_DIR}/conf.d/project/lua.d:${CMAKE_INSTALL_PREFIX}/controller-plugins/ctl-lua.d")
-else(CONTROL_SUPPORT_LUA)
- message(STATUS "Warning: LUA Without Support ")
-endif(CONTROL_SUPPORT_LUA)
-
-# Add target to project dependency list
-PROJECT_TARGET_ADD(control-afb)
-
- # Define project Targets
- ADD_LIBRARY(${TARGET_NAME} MODULE ctl-binding.c ctl-timer.c ctl-dispatch.c ${CTL_LUA_SOURCE})
-
- SET_OPENAPI_FILENAME("ctl-apidef")
- # Binder exposes a unique public entry point
- SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
- PREFIX "afb-"
- LABELS "BINDINGV2"
- LINK_FLAGS ${BINDINGS_LINK_FLAG}
- OUTPUT_NAME ${TARGET_NAME}
- )
-
- # Library dependencies (include updates automatically)
- TARGET_LINK_LIBRARIES(${TARGET_NAME}
- audio-common
- ${link_libraries}
- )
-
-
-PROJECT_TARGET_ADD(audio-plugin-sample)
-
- # Define targets
- ADD_LIBRARY(${TARGET_NAME} MODULE ctl-plugin-sample.c)
-
- # Alsa Plugin properties
- SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
- PREFIX ${CTL_PLUGIN_PRE}
- SUFFIX ${CTL_PLUGIN_EXT}
- OUTPUT_NAME ${TARGET_NAME}
- )
-
- # Library dependencies (include updates automatically)
- TARGET_LINK_LIBRARIES(${TARGET_NAME}
- audio-common
- ${link_libraries}
- )
-
- # installation directory
- INSTALL(TARGETS ${TARGET_NAME}
- LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/controler-plugins)
diff --git a/Controller-afb/README.md b/Controller-afb/README.md
deleted file mode 100644
index 9bab485..0000000
--- a/Controller-afb/README.md
+++ /dev/null
@@ -1,344 +0,0 @@
-Controler AAAA(AGL Advance Audio Controler) and more.
-------------------------------------------------------------
-
- * Object: Generic Controler to handle Policy,Small Business Logic, Glue in between components, ...
- * Status: Release Candidate
- * Author: Fulup Ar Foll fulup@iot.bzh
- * Date : August-2017
-
-## Functionalities:
- - Create an application dedicate controller from a JSON config file
- - Each controls (eg: navigation, multimedia, ...) is a suite of actions. When all actions succeed control is granted, if one fail control acces is denied.
- - Actions can either be:
- + Invocation to an other binding API, either internal or external (eg: a policy service, Alsa UCM, ...)
- + C routines from a user provider plugin (eg: policy routine, proprietary code, ...)
- + Lua script function. Lua provides access to every AGL appfw functionalities and can be extended from C user provided plugins.
-
-## Installation
- - Controler is a native part of AGL Advance Audio Framework but may be used independently with any other service or application binder.
- - Dependencies: the only dependencies are audio-common for JSON-WRAP and Filescan-utils capabilities.
- - Controler relies on Lua-5.3, when not needed Lua might be removed at compilation time.
-
-## Config
-
-Configuration is loaded dynamically during startup time. The controller scans CONTROL_CONFIG_PATH for a file corresponding to pattern
-"onload-bindername-xxxxx.json". When controller runs within AAAA binder it searches for "onload-audio-xxxx.json". First file found in the path the loaded
-any other files corresponding to the same pather are ignored and only generate a warning.
-
-Each bloc in the configuration file are defined with
- * label: must be provided is used either for debugging or as input for the action (eg: signal name, control name, ...)
- * info: optional used for documentation purpose only
-
-Note by default controller config search path is defined at compilation time, but path might be overloaded with CONTROL_CONFIG_PATH
-environment variable. Setenv 'CONTROL_ONLOAD_PROFILE'=xxxx to overload 'onload-default-profile' initialisation sequence.
-
-### Config is organised in 4 sections:
-
- * metadata
- * onload defines the set of action to be executed at startup time
- * control defines the set of controls with corresponding actions
- * event define the set of actions to be executed when receiving a given signal
-
-### Metadata
-
-As today matadata is only used for documentation purpose.
- * label + version mandatory
- * info optional
-
-### OnLoad section
-
-Defines startup time configuration. Onload may provide multiple initialisation profiles, each with a different label.
- * label is mandatory. Label is used to select onload profile at initialisation through DispatchOneOnLoad("onload-label") API;
- * info is optional
- * plugin provides optional unique plugin name. Plugin should follow "onload-bindername-xxxxx.ctlso" patern
- and are search into CONTROL_PLUGIN_PATH. When defined controller will execute user provided function context=CTLP_ONLOAD(label,version,info).
- The context returned by this routine is provided back to any C routines call later by the controller. Note that Lua2C function
- are prefix in Lua script with plugin label (eg: MyPlug: in following config sample)
- * lua2c list of Lua commands shipped with provided plugin.
- * require list of binding that should be initialised before the controller starts. Note that some listed requirer binding might be absent,
- nevertheless any present binding from this list will be started before controller binding, missing ones generate a warning.
- * action the list of action to execute during loadtime. Any failure in action will prevent controller binding from starting.
-
-### Control section
-
-Defines a list of controls that are accessible through (api="control", verb="request", control="control-label").
-
- * label mandatory
- * info optional
- * permissions Cynara needed privileges to request this control (same as AppFw-V2)
- * action the list of actions
-
-### Event section
-
-Defines a list of actions to be executed on event reception. Even can do anything a controller can (change state,
-send back signal, ...) eg: if a controller subscribes to vehicule speed, then speed-event may ajust master-volume to speed.
-
- * label mandatory
- * info optional
- * action the list of actions
-
-### Actions Categories
-
-Controler support tree categories of actions. Each action return a status status where 0=success and 1=failure.
- * AppFw API, Provides a generic model to request other bindings. Requested binding can be local (eg: ALSA/UCM) or
- external (eg: vehicle signalling).
- * api provides requested binding API name
- * verb provides verb to requested binding
- * args optionally provides a jsonc object for targeted binding API. Note that 'args' are statically defined
- in JSON configuration file. Controler client may also provided its own arguments from the query list. Targeted
- binding receives both arguments defined in the config file and the argument provided by controller client.
- * C-API, when defined in the onload section, the plugin may provided C native API with CTLP-CAPI(apiname, label, args, query, context).
- Plugin may also create Lua command with CTLP-Lua2C(LuaFuncName, label, args, query, context). Where args+query are JSONC object
- and context the value return from CTLP_ONLOAD function. Any missing value is set to NULL.
- * Lua-API, when compiled with Lua option, the controller support action defined directly in Lua script. During "onload" phase the
- controller search in CONTROL_Lua_PATH file with pattern "onload-bindername-xxxx.lua". Any file corresponding to this pattern
- is automatically loaded. Any function defined in those Lua script can be called through a controller action. Lua functions receive
- three parameters (label, args, query).
-
-Note: Lua added functions systematically prefix. AGL standard AppFw functions are prefixed with AGL: (eg: AGL:notice(), AGL_success(), ...).
-User Lua functions added though the plugin and CTLP_Lua2C are prefix with plugin label (eg: MyPlug:HelloWorld1).
-
-### Avaliable Application Framework Commands
-
-Each Lua AppFw commands should be prefixed by AFB:
-
- * AFB:notice ("format", arg1,... argn) LUA table are print directly as json string with '%s'.
- AFB:error, AFB:warning, AFB:info, AFB:debug work on the same model. Printed message are limited to 512 characters.
-
- * AFB:service ('API', 'VERB', {query}, "Lua_Callback_Name", {context}) asynchronous call to an other binding. When empty query/context should be set to '{}'
- and not to 'nil'. When 'nil' Lua does not send 'NULL' value but remove arguments to calling stack. WARNING:"Callback"
- is the name of the callback as a string and not a pointer to the callback. (If someone as a solution to fix this, please
- let me known). Callback is call as LUA "function Alsa_Get_Hal_CB (error, result, context)" where:
- * error is a Boolean
- * result is the full answer from AppFw (do not forget to extract response)
- * context is a copy of the Lua table pas as argument (warning it's a copy not a pointer to original table)
-
- * error,result=AFB:servsync('API', 'VERB', {query}) Save as previous but for synchronous call. Note that Lua accept multiple
- return. AFB:servsync return both the error message and the response as a Lua table. Like for AFB:service user should not
- forget to extract response from result.
-
- * AFB:success(request, response) request is the opaque handle pass when Lua is called from (api="control", verb="docall").
- Response is a Lua table that will be return to client.
-
- * AFB:fail(request, response) same as for success. Note that LUA generate automatically the error code from Lua function name.
- The response is tranformed to a json string before being return to client.
-
- * EventHandle=AFB:evtmake("MyEventName") Create an event and return the handle as an opaque handle. Note that due to a limitation
- of json_object this opaque handle cannot be passed as argument in a callback context.
-
- * AFB:subscribe(request, MyEventHandle) Subscribe a given client to previously created event.
-
- * AFB:evtpush (MyEventHandle, MyEventData) Push an event to every subscribed client. MyEventData is a Lua table that will be
- send as a json object to corresponding clients.
-
- * timerHandle=AFB:timerset (MyTimer, "Timer_Test_CB", context) Initialise a timer from MyTimer Lua table. This table should contend 3 elements:
- MyTimer={[l"abel"]="MyTimerName", ["delay"]=timeoutInMs, ["count"]=nBOfCycles}. Note that is count==0 then timer is cycle
- infinitively. Context is a standard Lua table. This function return an opaque handle to be use to further control the timer.
-
- * AFB:timerclear(timerHandle) Kill an existing timer. Return an error when timer does not exit.
-
- * MyTimer=AFB:timerget(timerHandle) Return Label, Delay and Count of an active timer. Return an error when timerHandle does not
- point on an active timer.
-
-Note: Except for function call during binding initialisation period. Lua call are protected and should return clean message
- even when improperly used. If you find bug please report.
-
-### Adding Lua command from User Plugin
-
-User Plugin is optional and may provide either native C-action accessible directly from controller actions as defined in
-JSON config file, or alternatively may provide at set of Lua commands usable inside any script (onload, control,event). A simple
-plugin that provide both natice C API and Lua commands is provided as example (see ctl-plugin-sample.c). Technically a
-plugin is a simple sharelibrary and any code fitting in sharelib might be used as a plugin. Developer should nevertheless
-not forget that except when no-concurrency flag was at binding construction time, any binding should to be thread safe.
-
-A plugin must be declare with CTLP_REGISTER("MyCtlSamplePlugin"). This entry point defines a special structure that is check
-at plugin load time by the controller. Then you have an optional init routine declare with CTLP_ONLOAD(label, version, info).
-This init routine receives controller onload profile as selected by DispatchOnLoad("profile"). The init routine may create
-a plugin context that is later one presented to every plugin API this for both LUA and native C ones. Then each:
-
- * C API declare with CTLP_CAPI (MyCFunction, label, argsJ, queryJ, context) {your code}. Where:
- * MyFunction is your function
- * Label is a string containing the name of your function
- * ArgsJ a json_object containing the argument attach the this control in JSON config file.
- * context your C context as return from CTLP_ONLOAD
-
- * Lua API declarewith TLP_LUA2C (MyLuaCFunction, label, argsJ, context) {your code}. Where
- * MyLuaCFunction is both the name of your C function and Lua command
- * Label your function name as a string
- * Args the arguments passed this time from Lua script and not from Json config file.
- * Query is not provided as LuaC function are called from a script and not directly from controller action list.
-
-Warning: Lua samples use with controller enforce strict mode. As a result every variables should be declare either as
-local or as global. Unfortunately "luac" is not smart enough to handle strict mode at build time and errors only appear
-at run time. Because of this strict mode every global variables (which include functions) should be prefix by '_'.
-Note that LUA require an initialisation value for every variables and declaring something like "local myvar" wont
-allocate "myvar"
-
-### Debugging Facilities
-
-Controler Lua script are check for syntax from CMAKE template with Luac. When needed to go further an developer API allow to
-execute directly Lua command within controller context from Rest/Ws (api=control, verb=lua_doscript). DoScript API takes two
-other optional arguments func=xxxx where xxxx is the function to execute within Lua script and args a JSON object to provide
-input parameter. When funcname is not given by default the controller try to execute middle filename doscript-xxxx-????.lua.
-
-When executed from controller Lua script may use any AppFw Apis as well as any L2C user defined commands in plugin.
-
-### Running as Standalone Controller
-
-Controller is a standard binding and can then be started independently of AAAA. When started with from build repository with
-```
-afb-daemon --port=1234 --workdir=. --roothttp=../htdocs --tracereq=common --token= --verbose --binding=./Controller-afb/afb-control-afb.so
-```
-
-Afb-Daemon only load controller bindings without search for the other binding. In this case the name of the process is not change
-to afb-audio and controller binding will search for a configuration file name 'onload-daemon-xxx.json'. This model can be used
-to implement for testing purpose or simply to act as the glue in between a UI and other binder/services.
-
-## Config Sample
-
-Here after a simple configuration sample.
-
-```
-{
- "$schema": "ToBeDone",
- "metadata": {
- "label": "sample-audio-control",
- "info": "Provide Default Audio Policy for Multimedia, Navigation and Emergency",
- "version": "1.0"
- },
- "onload": [{
- "label": "onload-default",
- "info": "onload initialisation config",
- "plugin": {
- "label" : "MyPlug",
- "sharelib": "ctl-audio-plugin-sample.ctlso",
- "lua2c": ["Lua2cHelloWorld1", "Lua2cHelloWorld2"]
- },
- "require": ["intel-hda", "jabra-usb", "scarlett-usb"],
- "actions": [
- {
- "label": "onload-sample-cb",
- "info": "Call control sharelib install entrypoint",
- "callback": "SamplePolicyInit",
- "args": {
- "arg1": "first_arg",
- "nextarg": "second arg value"
- }
- }, {
- "label": "onload-sample-api",
- "info": "Assert AlsaCore Presence",
- "api": "alsacore",
- "verb": "ping",
- "args": "test"
- }, {
- "label": "onload-hal-lua",
- "info": "Load avaliable HALs",
- "lua": "Audio_Init_Hal"
- }
- ]
- }],
- "controls":
- [
- {
- "label": "multimedia",
- "permissions": "urn:AGL:permission:audio:public:mutimedia",
- "actions": {
- "label": "multimedia-control-lua",
- "info": "Call Lua Script function Test_Lua_Engin",
- "lua": "Audio_Set_Multimedia"
- }
- }, {
- "label": "navigation",
- "permissions": "urn:AGL:permission:audio:public:navigation",
- "actions": {
- "label": "navigation-control-lua",
- "info": "Call Lua Script to set Navigation",
- "lua": "Audio_Set_Navigation"
- }
- }, {
- "label": "emergency",
- "permissions": "urn:AGL:permission:audio:public:emergency",
- "actions": {
- "label": "emergency-control-ucm",
- "lua": "Audio_Set_Emergency"
- }
- }, {
- "label": "multi-step-sample",
- "info" : "all actions must succeed for control to be accepted",
- "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": {
- "test": "navigation"
- }
- }, {
- "label": "navigation-control-lua",
- "info": "Call Lua Script to set Navigation",
- "lua": "Audio_Set_Navigation"
- }]
- }
- ],
- "events":
- [
- {
- "label": "Vehicle-Speed",
- "info": "Action when Vehicule speed change",
- "actions": [
- {
- "label": "speed-action-1",
- "callback": "Blink-when-over-130",
- "args": {
- "speed": 130
- "blink-speed": 1000
- }
- }, {
- "label": "Adjust-Volume",
- "lua": "Adjust_Volume_To_Speed",
- }
- ]
- },
- {
- "label": "Reverse-Engage",
- "info": "When Reverse Gear is Engage",
- "actions": [
- {
- "label": "Display-Rear-Camera",
- "callback": "Display-Rear-Camera",
- }, {
- "label": "Prevent-Phone-Call",
- "api" : "phone",
- "verb" : "status",
- "args": {
- "call-accepted": false
- }
- }
- ]
- },
- {
- "label": "Neutral-Engage",
- "info": "When Reverse Neutral is Engage",
- "actions": [
- {
- "label": "Authorize-Video",
- "api" : "video",
- "verb" : "status",
- "args": {
- "tv-accepted": true
- }
- }
- ]
- }
- ]
-}
-
-```
-
diff --git a/Controller-afb/a.out b/Controller-afb/a.out
deleted file mode 100755
index d18064f..0000000
--- a/Controller-afb/a.out
+++ /dev/null
Binary files differ
diff --git a/Controller-afb/ctl-apidef.h b/Controller-afb/ctl-apidef.h
deleted file mode 100644
index 9ce9e05..0000000
--- a/Controller-afb/ctl-apidef.h
+++ /dev/null
@@ -1,103 +0,0 @@
-
-static const char _afb_description_v2_control[] =
- "{\"openapi\":\"3.0.0\",\"$schema\":\"http:iot.bzh/download/openapi/schem"
- "a-3.0/default-schema.json\",\"info\":{\"description\":\"\",\"title\":\"c"
- "ontroler\",\"version\":\"1.0\",\"x-binding-c-generator\":{\"api\":\"cont"
- "rol\",\"version\":2,\"prefix\":\"ctlapi_\",\"postfix\":\"\",\"start\":nu"
- "ll,\"onevent\":\"DispatchOneEvent\",\"init\":\"CtlBindingInit\",\"scope\""
- ":\"\",\"private\":false}},\"servers\":[{\"url\":\"ws://{host}:{port}/api"
- "/polctl\",\"description\":\"Unicens2 API.\",\"variables\":{\"host\":{\"d"
- "efault\":\"localhost\"},\"port\":{\"default\":\"1234\"}},\"x-afb-events\""
- ":[{\"$ref\":\"#/components/schemas/afb-event\"}]}],\"components\":{\"sch"
- "emas\":{\"afb-reply\":{\"$ref\":\"#/components/schemas/afb-reply-v2\"},\""
- "afb-event\":{\"$ref\":\"#/components/schemas/afb-event-v2\"},\"afb-reply"
- "-v2\":{\"title\":\"Generic response.\",\"type\":\"object\",\"required\":"
- "[\"jtype\",\"request\"],\"properties\":{\"jtype\":{\"type\":\"string\",\""
- "const\":\"afb-reply\"},\"request\":{\"type\":\"object\",\"required\":[\""
- "status\"],\"properties\":{\"status\":{\"type\":\"string\"},\"info\":{\"t"
- "ype\":\"string\"},\"token\":{\"type\":\"string\"},\"uuid\":{\"type\":\"s"
- "tring\"},\"reqid\":{\"type\":\"string\"}}},\"response\":{\"type\":\"obje"
- "ct\"}}},\"afb-event-v2\":{\"type\":\"object\",\"required\":[\"jtype\",\""
- "event\"],\"properties\":{\"jtype\":{\"type\":\"string\",\"const\":\"afb-"
- "event\"},\"event\":{\"type\":\"string\"},\"data\":{\"type\":\"object\"}}"
- "}},\"x-permissions\":{\"monitor\":{\"permission\":\"urn:AGL:permission:a"
- "udio:public:monitor\"},\"multimedia\":{\"permission\":\"urn:AGL:permissi"
- "on:audio:public:monitor\"},\"navigation\":{\"permission\":\"urn:AGL:perm"
- "ission:audio:public:monitor\"},\"emergency\":{\"permission\":\"urn:AGL:p"
- "ermission:audio:public:emergency\"}},\"responses\":{\"200\":{\"descripti"
- "on\":\"A complex object array response\",\"content\":{\"application/json"
- "\":{\"schema\":{\"$ref\":\"#/components/schemas/afb-reply\"}}}}}},\"path"
- "s\":{\"/monitor\":{\"description\":\"Subcribe Audio Agent Policy Control"
- " End\",\"get\":{\"x-permissions\":{\"$ref\":\"#/components/x-permissions"
- "/monitor\"},\"parameters\":[{\"in\":\"query\",\"name\":\"event_patern\","
- "\"required\":true,\"schema\":{\"type\":\"string\"}}],\"responses\":{\"20"
- "0\":{\"$ref\":\"#/components/responses/200\"}}}},\"/dispatch\":{\"descri"
- "ption\":\"Request Access to Navigation Audio Channel.\",\"get\":{\"x-per"
- "missions\":{\"$ref\":\"#/components/x-permissions/navigation\"},\"parame"
- "ters\":[{\"in\":\"query\",\"name\":\"zone\",\"required\":false,\"schema\""
- ":{\"type\":\"string\"}}],\"responses\":{\"200\":{\"$ref\":\"#/components"
- "/responses/200\"}}}},\"/request\":{\"description\":\"Execute LUA string "
- "script.\",\"get\":{\"x-permissions\":{\"$ref\":\"#/components/x-permissi"
- "ons/navigation\"},\"parameters\":[{\"in\":\"query\",\"name\":\"func\",\""
- "required\":true,\"schema\":{\"type\":\"string\"}},{\"in\":\"query\",\"na"
- "me\":\"args\",\"required\":false,\"schema\":{\"type\":\"array\"}}],\"res"
- "ponses\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}}},\"/debugl"
- "ua\":{\"description\":\"Execute LUA string script.\",\"get\":{\"x-permis"
- "sions\":{\"$ref\":\"#/components/x-permissions/navigation\"},\"parameter"
- "s\":[{\"in\":\"query\",\"name\":\"filename\",\"required\":true,\"schema\""
- ":{\"type\":\"string\"}}],\"responses\":{\"200\":{\"$ref\":\"#/components"
- "/responses/200\"}}}}}}"
-;
-
-static const struct afb_auth _afb_auths_v2_control[] = {
- { .type = afb_auth_Permission, .text = "urn:AGL:permission:audio:public:monitor" }
-};
-
- void ctlapi_monitor(struct afb_req req);
- void ctlapi_dispatch(struct afb_req req);
- void ctlapi_request(struct afb_req req);
- void ctlapi_debuglua(struct afb_req req);
-
-static const struct afb_verb_v2 _afb_verbs_v2_control[] = {
- {
- .verb = "monitor",
- .callback = ctlapi_monitor,
- .auth = &_afb_auths_v2_control[0],
- .info = NULL,
- .session = AFB_SESSION_NONE_V2
- },
- {
- .verb = "dispatch",
- .callback = ctlapi_dispatch,
- .auth = &_afb_auths_v2_control[0],
- .info = NULL,
- .session = AFB_SESSION_NONE_V2
- },
- {
- .verb = "request",
- .callback = ctlapi_request,
- .auth = &_afb_auths_v2_control[0],
- .info = NULL,
- .session = AFB_SESSION_NONE_V2
- },
- {
- .verb = "debuglua",
- .callback = ctlapi_debuglua,
- .auth = &_afb_auths_v2_control[0],
- .info = NULL,
- .session = AFB_SESSION_NONE_V2
- },
- { .verb = NULL }
-};
-
-const struct afb_binding_v2 afbBindingV2 = {
- .api = "control",
- .specification = _afb_description_v2_control,
- .info = NULL,
- .verbs = _afb_verbs_v2_control,
- .preinit = NULL,
- .init = CtlBindingInit,
- .onevent = DispatchOneEvent,
- .noconcurrency = 0
-};
-
diff --git a/Controller-afb/ctl-apidef.json b/Controller-afb/ctl-apidef.json
deleted file mode 100644
index e2207d0..0000000
--- a/Controller-afb/ctl-apidef.json
+++ /dev/null
@@ -1,228 +0,0 @@
-{
- "openapi": "3.0.0",
- "$schema": "http:iot.bzh/download/openapi/schema-3.0/default-schema.json",
- "info": {
- "description": "",
- "title": "controler",
- "version": "1.0",
- "x-binding-c-generator": {
- "api": "control",
- "version": 2,
- "prefix": "ctlapi_",
- "postfix": "",
- "start": null,
- "onevent": "DispatchOneEvent",
- "init": "CtlBindingInit",
- "scope": "",
- "private": false
- }
- },
- "servers": [
- {
- "url": "ws://{host}:{port}/api/polctl",
- "description": "Unicens2 API.",
- "variables": {
- "host": {
- "default": "localhost"
- },
- "port": {
- "default": "1234"
- }
- },
- "x-afb-events": [
- {
- "$ref": "#/components/schemas/afb-event"
- }
- ]
- }
- ],
- "components": {
- "schemas": {
- "afb-reply": {
- "$ref": "#/components/schemas/afb-reply-v2"
- },
- "afb-event": {
- "$ref": "#/components/schemas/afb-event-v2"
- },
- "afb-reply-v2": {
- "title": "Generic response.",
- "type": "object",
- "required": ["jtype", "request"],
- "properties": {
- "jtype": {
- "type": "string",
- "const": "afb-reply"
- },
- "request": {
- "type": "object",
- "required": ["status"],
- "properties": {
- "status": {
- "type": "string"
- },
- "info": {
- "type": "string"
- },
- "token": {
- "type": "string"
- },
- "uuid": {
- "type": "string"
- },
- "reqid": {
- "type": "string"
- }
- }
- },
- "response": {
- "type": "object"
- }
- }
- },
- "afb-event-v2": {
- "type": "object",
- "required": ["jtype", "event"],
- "properties": {
- "jtype": {
- "type": "string",
- "const": "afb-event"
- },
- "event": {
- "type": "string"
- },
- "data": {
- "type": "object"
- }
- }
- }
- },
- "x-permissions": {
- "monitor": {
- "permission": "urn:AGL:permission:audio:public:monitor"
- },
- "multimedia": {
- "permission": "urn:AGL:permission:audio:public:monitor"
- },
- "navigation": {
- "permission": "urn:AGL:permission:audio:public:monitor"
- },
- "emergency": {
- "permission": "urn:AGL:permission:audio:public:emergency"
- }
- },
- "responses": {
- "200": {
- "description": "A complex object array response",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/afb-reply"
- }
- }
- }
- }
- }
- },
- "paths": {
- "/monitor": {
- "description": "Subcribe Audio Agent Policy Control End",
- "get": {
- "x-permissions": {
- "$ref": "#/components/x-permissions/monitor"
- },
- "parameters": [
- {
- "in": "query",
- "name": "event_patern",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "$ref": "#/components/responses/200"
- }
- }
- }
- },
- "/dispatch": {
- "description": "Request Access to Navigation Audio Channel.",
- "get": {
- "x-permissions": {
- "$ref": "#/components/x-permissions/navigation"
- },
- "parameters": [
- {
- "in": "query",
- "name": "zone",
- "required": false,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "$ref": "#/components/responses/200"
- }
- }
- }
- },
- "/request": {
- "description": "Execute LUA string script.",
- "get": {
- "x-permissions": {
- "$ref": "#/components/x-permissions/navigation"
- },
- "parameters": [
- {
- "in": "query",
- "name": "func",
- "required": true,
- "schema": {
- "type": "string"
- }
- },
- {
- "in": "query",
- "name": "args",
- "required": false,
- "schema": {
- "type": "array"
- }
- }
- ],
- "responses": {
- "200": {
- "$ref": "#/components/responses/200"
- }
- }
- }
- },
- "/debuglua": {
- "description": "Execute LUA string script.",
- "get": {
- "x-permissions": {
- "$ref": "#/components/x-permissions/navigation"
- },
- "parameters": [
- {
- "in": "query",
- "name": "filename",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "$ref": "#/components/responses/200"
- }
- }
- }
- }
- }
-}
diff --git a/Controller-afb/ctl-binding.c b/Controller-afb/ctl-binding.c
deleted file mode 100644
index ec33f82..0000000
--- a/Controller-afb/ctl-binding.c
+++ /dev/null
@@ -1,68 +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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-
-#include "audio-common.h"
-#include "ctl-binding.h"
-
-
-
-// Include Binding Stub generated from Json OpenAPI
-#include "ctl-apidef.h"
-
-
-PUBLIC void ctlapi_monitor (afb_req request) {
-
- // subscribe Client to event
- int err = afb_req_subscribe(request, TimerEvtGet());
- if (err != 0) {
- afb_req_fail_f(request, "register-event", "Fail to subscribe binder event");
- goto OnErrorExit;
- }
-
- afb_req_success(request, NULL, NULL);
-
- OnErrorExit:
- return;
-}
-
-// Create Binding Event at Init
-PUBLIC int CtlBindingInit () {
-
- int errcount=0;
-
- errcount += TimerEvtInit();
- errcount += DispatchInit();
-#ifdef CONTROL_SUPPORT_LUA
- errcount += LuaLibInit();
-#endif
-
- const char *profile= getenv("CONTROL_ONLOAD_PROFILE");
- if (!profile) profile=CONTROL_ONLOAD_PROFILE;
-
- // now that everything is initialised execute the onload action
- if (!errcount)
- errcount += DispatchOnLoad(CONTROL_ONLOAD_PROFILE);
-
- AFB_DEBUG ("Audio Policy Control Binding Done errcount=%d", errcount);
- return errcount;
-}
-
diff --git a/Controller-afb/ctl-binding.h b/Controller-afb/ctl-binding.h
deleted file mode 100644
index a1c7ef2..0000000
--- a/Controller-afb/ctl-binding.h
+++ /dev/null
@@ -1,146 +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.
- */
-
-
-#ifndef CONTROLLER_BINDING_INCLUDE
-#define CONTROLLER_BINDING_INCLUDE
-
-#define AFB_BINDING_VERSION 2
-#include <afb/afb-binding.h>
-#include <json-c/json.h>
-#include <filescan-utils.h>
-#include <wrap-json.h>
-#include <systemd/sd-event.h>
-
-
-#ifdef CONTROL_SUPPORT_LUA
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
-#endif
-
-#ifndef PUBLIC
- #define PUBLIC
-#endif
-#define STATIC static
-
-#ifndef UNUSED_ARG
-#define UNUSED_ARG(x) UNUSED_ ## x __attribute__((__unused__))
-#define UNUSED_FUNCTION(x) __attribute__((__unused__)) UNUSED_ ## x
-#endif
-
-// polctl-binding.c
-PUBLIC int CtlBindingInit ();
-
-// ctl-timerevt.c
-// ----------------------
-typedef int (*timerCallbackT)(void *context);
-
-typedef struct TimerHandleS {
- int count;
- int delay;
- const char*label;
- void *context;
- timerCallbackT callback;
- sd_event_source *evtSource;
-} TimerHandleT;
-
-PUBLIC int TimerEvtInit (void);
-PUBLIC afb_event TimerEvtGet(void);
-PUBLIC void TimerEvtStart(TimerHandleT *timerHandle, timerCallbackT callback, void *context);
-PUBLIC void TimerEvtStop(TimerHandleT *timerHandle);
-
-// ctl-policy
-// -----------
-
-typedef enum {
- CTL_MODE_NONE=0,
- CTL_MODE_API,
- CTL_MODE_CB,
- CTL_MODE_LUA,
-} CtlRequestModeT;
-
-
-typedef enum {
- CTL_SOURCE_CLOSE=-1,
- CTL_SOURCE_UNKNOWN=0,
- CTL_SOURCE_ONLOAD=1,
- CTL_SOURCE_OPEN=2,
- CTL_SOURCE_EVENT=3,
-} DispatchSourceT;
-
-typedef struct DispatchActionS{
- const char *info;
- const char* label;
- CtlRequestModeT mode;
- const char* api;
- const char* call;
- json_object *argsJ;
- int timeout;
- int (*actionCB)(DispatchSourceT source, const char*label, json_object *argsJ, json_object *queryJ, void *context);
-} DispatchActionT;
-
-typedef int (*Lua2cFunctionT)(char *funcname, json_object *argsJ, void*context);
-
-PUBLIC int DispatchInit(void);
-PUBLIC int DispatchOnLoad(const char *onLoadLabel);
-PUBLIC void DispatchOneEvent(const char *evtLabel, json_object *eventJ);
-PUBLIC int DispatchOneL2c(lua_State* luaState, char *funcname, Lua2cFunctionT callback);
-PUBLIC void ctlapi_dispatch (afb_req request);
-
-#ifdef CONTROL_SUPPORT_LUA
-// ctl-lua.c
-typedef int (*Lua2cWrapperT) (lua_State* luaState, char *funcname, Lua2cFunctionT callback);
-
-#define CTLP_LUA2C(FuncName, label,argsJ, context) static int FuncName(char*label,json_object*argsJ, void*context);\
- int lua2c_ ## FuncName(lua_State* luaState){return((*Lua2cWrap)(luaState, MACRO_STR_VALUE(FuncName), FuncName));};\
- static int FuncName(char* label, json_object* argsJ, void* context)
-
-typedef enum {
- LUA_DOCALL,
- LUA_DOSTRING,
- LUA_DOSCRIPT,
-} LuaDoActionT;
-
-PUBLIC int LuaLibInit ();
-PUBLIC void LuaL2cNewLib(const char *label, luaL_Reg *l2cFunc, int count);
-PUBLIC int Lua2cWrapper(lua_State* luaState, char *funcname, Lua2cFunctionT callback, void *context);
-PUBLIC int LuaCallFunc (DispatchSourceT source, DispatchActionT *action, json_object *queryJ) ;
-PUBLIC void ctlapi_lua_docall (afb_req request);
-PUBLIC void ctlapi_lua_dostring (afb_req request);
-PUBLIC void ctlapi_lua_doscript (afb_req request);
-
-#else
- typedef void* Lua2cWrapperT;
-#endif // CONTROL_SUPPORT_LUA
-
-
-// sharelib ctl-plugin*
-typedef struct {
- long magic;
- char *label;
-} CtlPluginMagicT;
-
-
-#define MACRO_STR_VALUE(arg) #arg
-#define CTLP_REGISTER(pluglabel) CtlPluginMagicT CtlPluginMagic={.magic=CTL_PLUGIN_MAGIC,.label=pluglabel}; struct afb_binding_data_v2; Lua2cWrapperT Lua2cWrap;
-#define CTLP_ONLOAD(label,version,info) void* CtlPluginOnload(char* label, char* version, char* info)
-#define CTLP_CAPI(funcname,source, label,argsJ, queryJ, context) int funcname(DispatchSourceT source, char* label, json_object* argsJ, json_object* queryJ, void* context)
-
-
-
-#endif // CONTROLLER_BINDING_INCLUDE
diff --git a/Controller-afb/ctl-dispatch.c b/Controller-afb/ctl-dispatch.c
deleted file mode 100644
index 0104229..0000000
--- a/Controller-afb/ctl-dispatch.c
+++ /dev/null
@@ -1,667 +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.
- *
- * 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 "ctl-binding.h"
-
-typedef void*(*DispatchPluginInstallCbT)(const char* label, const char*version, const char*info);
-
-
-static afb_req NULL_AFBREQ = {};
-
-
-typedef struct {
- const char* label;
- const char *info;
- DispatchActionT *actions;
-} DispatchHandleT;
-
-typedef struct {
- const char *label;
- const char *info;
- void *context;
- char *sharelib;
- void *dlHandle;
- luaL_Reg *l2cFunc;
- int l2cCount;
-} DispatchPluginT;
-
-typedef struct {
- const char* label;
- const char *info;
- const char *version;
- DispatchPluginT *plugin;
- DispatchHandleT **onloads;
- DispatchHandleT **events;
- DispatchHandleT **controls;
-} DispatchConfigT;
-
-// global config handle
-STATIC DispatchConfigT *configHandle = NULL;
-
-STATIC int DispatchControlToIndex(DispatchHandleT **controls, const char* controlLabel) {
-
- for (int idx = 0; controls[idx]; idx++) {
- if (!strcasecmp(controlLabel, controls[idx]->label)) return idx;
- }
- return -1;
-}
-
-STATIC int DispatchOneControl(DispatchSourceT source, DispatchHandleT **controls, const char* controlLabel, json_object *queryJ, afb_req request) {
- int err;
-
- if (!configHandle) {
- AFB_ERROR("DISPATCH-CTL-API: (Hoops/Bug!!!) No Config Loaded");
- goto OnErrorExit;
- }
-
- if (!configHandle->controls) {
- AFB_ERROR("DISPATCH-CTL-API: No Control Action in Json config label=%s version=%s", configHandle->label, configHandle->version);
- goto OnErrorExit;
- }
-
- int index = DispatchControlToIndex(controls, controlLabel);
- if (index < 0 || !controls[index]->actions) {
- AFB_ERROR("DISPATCH-CTL-API:NotFound/Error label=%s in Json Control Config File", controlLabel);
- goto OnErrorExit;
- }
-
- // Fulup (Bug/Feature) in current version is unique to every onload profile
- if (configHandle->plugin && configHandle->plugin->l2cCount) {
- LuaL2cNewLib (configHandle->plugin->label, configHandle->plugin->l2cFunc, configHandle->plugin->l2cCount);
- }
-
- // loop on action for this control
- DispatchActionT *actions = controls[index]->actions;
- for (int idx = 0; actions[idx].label; idx++) {
-
- switch (actions[idx].mode) {
- case CTL_MODE_API:
- {
- json_object *returnJ;
-
- // if query is empty increment usage count and pass args
- if (!queryJ || json_object_get_type(queryJ) != json_type_object) {
- json_object_get(actions[idx].argsJ);
- queryJ= actions[idx].argsJ;
- } else if (actions[idx].argsJ) {
-
- // Merge queryJ and argsJ before sending request
- if (json_object_get_type(actions[idx].argsJ) == json_type_object) {
- json_object_object_foreach(actions[idx].argsJ, key, val) {
- json_object_object_add(queryJ, key, val);
- }
- } else {
- json_object_object_add(queryJ, "args", actions[idx].argsJ);
- }
- }
-
- int err = afb_service_call_sync(actions[idx].api, actions[idx].call, queryJ, &returnJ);
- if (err) {
- static const char*format = "DispatchOneControl(Api) api=%s verb=%s args=%s";
- if (afb_req_is_valid(request))afb_req_fail_f(request, "DISPATCH-CTL-MODE:API", format, actions[idx].label, actions[idx].api, actions[idx].call);
- else AFB_ERROR(format, actions[idx].api, actions[idx].call, actions[idx].label);
- goto OnErrorExit;
- }
- break;
- }
-
-#ifdef CONTROL_SUPPORT_LUA
- case CTL_MODE_LUA:
- err = LuaCallFunc(source, &actions[idx], queryJ);
- if (err) {
- static const char*format = "DispatchOneControl(Lua) label=%s func=%s args=%s";
- if (afb_req_is_valid(request)) afb_req_fail_f(request, "DISPATCH-CTL-MODE:Lua", format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ));
- else AFB_ERROR(format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ));
- goto OnErrorExit;
- }
- break;
-#endif
-
- case CTL_MODE_CB:
- err = (*actions[idx].actionCB) (source, actions[idx].label, actions[idx].argsJ, queryJ, configHandle->plugin->context);
- if (err) {
- static const char*format = "DispatchOneControl(Callback) label%s func=%s args=%s";
- if (afb_req_is_valid(request)) afb_req_fail_f(request, "DISPATCH-CTL-MODE:Cb", format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ));
- else AFB_ERROR(format, actions[idx].label, actions[idx].call, json_object_get_string(actions[idx].argsJ));
- goto OnErrorExit;
- }
- break;
-
- default:
- {
- static const char*format = "DispatchOneControl(unknown) mode control=%s action=%s";
- AFB_ERROR(format, controls[index]->label);
- if (afb_req_is_valid(request))afb_req_fail_f(request, "DISPATCH-CTL-MODE:Unknown", format, controls[index]->label);
- }
- }
- }
-
- // everything when fine
- if (afb_req_is_valid(request))afb_req_success(request, NULL, controls[index]->label);
- return 0;
-
-OnErrorExit:
- return -1;
-}
-
-
-// Event name is mapped on control label and executed as a standard control
-
-PUBLIC void DispatchOneEvent(const char *evtLabel, json_object *eventJ) {
- DispatchHandleT **events = configHandle->events;
-
- (void) DispatchOneControl(CTL_SOURCE_EVENT, events, evtLabel, eventJ, NULL_AFBREQ);
-}
-
-// Event name is mapped on control label and executed as a standard control
-
-PUBLIC int DispatchOnLoad(const char *onLoadLabel) {
- if (!configHandle) return 1;
-
- DispatchHandleT **onloads = configHandle->onloads;
-
- int err = DispatchOneControl(CTL_SOURCE_ONLOAD, onloads, onLoadLabel, NULL, NULL_AFBREQ);
- return err;
-}
-
-PUBLIC void ctlapi_dispatch(afb_req request) {
- DispatchHandleT **controls = configHandle->controls;
- json_object *queryJ, *argsJ=NULL;
- const char *target;
- DispatchSourceT source= CTL_SOURCE_UNKNOWN;
-
- queryJ = afb_req_json(request);
- int err = wrap_json_unpack(queryJ, "{s:s, s?i s?o !}", "target", &target, "source", &source, "args", &argsJ);
- if (err) {
- afb_req_fail_f(request, "CTL-DISPTACH-INVALID", "missing target or args not a valid json object query=%s", json_object_get_string(queryJ));
- goto OnErrorExit;
- }
-
- (void) DispatchOneControl(source, controls, target, argsJ, request);
-
-OnErrorExit:
- return;
-}
-
-// Wrapper to Lua2c plugin command add context dans delegate to LuaWrapper
-PUBLIC int DispatchOneL2c(lua_State* luaState, char *funcname, Lua2cFunctionT callback) {
-#ifndef CONTROL_SUPPORT_LUA
- AFB_ERROR("DISPATCH-ONE-L2C: LUA support not selected (cf:CONTROL_SUPPORT_LUA) in config.cmake");
- return 1;
-#else
- int err=Lua2cWrapper(luaState, funcname, callback, configHandle->plugin->context);
- return err;
-#endif
-}
-
-
-// List Avaliable Configuration Files
-
-PUBLIC void ctlapi_config(struct afb_req request) {
- json_object*tmpJ;
- char *dirList;
-
-
- json_object* queryJ = afb_req_json(request);
- if (queryJ && json_object_object_get_ex(queryJ, "cfgpath", &tmpJ)) {
- dirList = strdup(json_object_get_string(tmpJ));
- } else {
-
- dirList = getenv("CONTROL_CONFIG_PATH");
- if (!dirList) dirList = strdup(CONTROL_CONFIG_PATH);
- AFB_NOTICE("CONFIG-MISSING: use default CONTROL_CONFIG_PATH=%s", CONTROL_CONFIG_PATH);
- }
-
- // get list of config file
- struct json_object *responseJ = ScanForConfig(dirList, CTL_SCAN_RECURSIVE, "onload", "json");
-
- if (json_object_array_length(responseJ) == 0) {
- afb_req_fail(request, "CONFIGPATH:EMPTY", "No Config Found in CONTROL_CONFIG_PATH");
- } else {
- afb_req_success(request, responseJ, NULL);
- }
-
- return;
-}
-
-// unpack individual action object
-
-STATIC int DispatchLoadOneAction(DispatchConfigT *controlConfig, json_object *actionJ, DispatchActionT *action) {
- char *api = NULL, *verb = NULL, *callback = NULL, *lua = NULL;
- int err, modeCount = 0;
-
- err = wrap_json_unpack(actionJ, "{ss,s?s,s?s,s?s,s?s,s?s,s?o !}"
- , "label", &action->label, "info", &action->info, "callback", &callback, "lua", &lua, "api", &api, "verb", &verb, "args", &action->argsJ);
- 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 && controlConfig->plugin) {
- action->mode = CTL_MODE_CB;
- action->call = callback;
- modeCount++;
-
- action->actionCB = dlsym(controlConfig->plugin->dlHandle, callback);
- if (!action->actionCB) {
- AFB_ERROR("DISPATCH-LOAD-ACTION fail to find calbback=%s in %s", callback, controlConfig->plugin->sharelib);
- goto OnErrorExit;
- }
- }
-
- // make sure at least one mode is selected
- if (modeCount == 0) {
- AFB_ERROR("DISPATCH-LOAD-ACTION No Action Selected lua|callback|(api+verb) in %s", json_object_get_string(actionJ));
- goto OnErrorExit;
- }
-
- if (modeCount > 1) {
- AFB_ERROR("DISPATCH-LOAD-ACTION:ToMany arguments lua|callback|(api+verb) in %s", json_object_get_string(actionJ));
- goto OnErrorExit;
- }
- return 0;
-
-OnErrorExit:
- return -1;
-};
-
-STATIC DispatchActionT *DispatchLoadActions(DispatchConfigT *controlConfig, json_object *actionsJ) {
- int err;
- DispatchActionT *actions;
-
- // action array is close with a nullvalue;
- if (json_object_get_type(actionsJ) == json_type_array) {
- int count = json_object_array_length(actionsJ);
- actions = calloc(count + 1, sizeof (DispatchActionT));
-
- for (int idx = 0; idx < count; idx++) {
- json_object *actionJ = json_object_array_get_idx(actionsJ, idx);
- err = DispatchLoadOneAction(controlConfig, actionJ, &actions[idx]);
- if (err) goto OnErrorExit;
- }
-
- } else {
- actions = calloc(2, sizeof (DispatchActionT));
- err = DispatchLoadOneAction(controlConfig, actionsJ, &actions[0]);
- if (err) goto OnErrorExit;
- }
-
- return actions;
-
-OnErrorExit:
- return NULL;
-
-}
-
-STATIC DispatchHandleT *DispatchLoadControl(DispatchConfigT *controlConfig, json_object *controlJ) {
- json_object *actionsJ, *permissionsJ;
- int err;
-
- DispatchHandleT *dispatchHandle = calloc(1, sizeof (DispatchHandleT));
- err = wrap_json_unpack(controlJ, "{ss,s?s,s?o, so !}", "label", &dispatchHandle->label, "info", &dispatchHandle->info
- , "permissions", &permissionsJ, "actions", &actionsJ);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:CONTROL Missing something label|[info]|actions in %s", json_object_get_string(controlJ));
- goto OnErrorExit;
- }
-
- dispatchHandle->actions = DispatchLoadActions(controlConfig, actionsJ);
- if (!dispatchHandle->actions) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:CONTROL Error when parsing actions %s", dispatchHandle->label);
- goto OnErrorExit;
- }
- return dispatchHandle;
-
-OnErrorExit:
- return NULL;
-}
-
-STATIC DispatchHandleT *DispatchLoadOnload(DispatchConfigT *controlConfig, json_object *onloadJ) {
- json_object *actionsJ = NULL, *requireJ = NULL, *pluginJ = NULL;
- int err;
-
- DispatchHandleT *dispatchHandle = calloc(1, sizeof (DispatchHandleT));
- err = wrap_json_unpack(onloadJ, "{ss,s?s, s?o,s?o,s?o !}",
- "label", &dispatchHandle->label, "info", &dispatchHandle->info, "plugin", &pluginJ, "require", &requireJ, "actions", &actionsJ);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:ONLOAD Missing something label|[info]|[plugin]|[actions] in %s", json_object_get_string(onloadJ));
- goto OnErrorExit;
- }
-
- // best effort to initialise everything before starting
- if (requireJ) {
-
- void DispatchRequireOneApi(json_object * bindindJ) {
- const char* requireBinding = json_object_get_string(bindindJ);
- err = afb_daemon_require_api(requireBinding, 1);
- if (err) {
- AFB_WARNING("DISPATCH-LOAD-CONFIG:REQUIRE Fail to get=%s", requireBinding);
- }
- }
-
- if (json_object_get_type(requireJ) == json_type_array) {
- for (int idx = 0; idx < json_object_array_length(requireJ); idx++) {
- DispatchRequireOneApi(json_object_array_get_idx(requireJ, idx));
- }
- } else {
- DispatchRequireOneApi(requireJ);
- }
- }
-
- if (pluginJ) {
- json_object *lua2csJ = NULL;
- DispatchPluginT *dPlugin= calloc(1, sizeof(DispatchPluginT));
- controlConfig->plugin = dPlugin;
- const char*ldSearchPath=NULL;
-
- err = wrap_json_unpack(pluginJ, "{ss,s?s,s?s,ss,s?o!}",
- "label", &dPlugin->label, "info", &dPlugin->info, "ldpath", &ldSearchPath, "sharelib", &dPlugin->sharelib, "lua2c", &lua2csJ);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:ONLOAD Plugin missing label|[info]|sharelib|[lua2c] in %s", json_object_get_string(onloadJ));
- goto OnErrorExit;
- }
-
- // if search path not in Json config file, then try default
- if (!ldSearchPath) ldSearchPath=CONTROL_PLUGIN_PATH;
-
- // search for default policy config file
- json_object *pluginPathJ = ScanForConfig(ldSearchPath, CTL_SCAN_RECURSIVE, dPlugin->sharelib, NULL);
- if (!pluginPathJ || json_object_array_length(pluginPathJ) == 0) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:PLUGIN Missing plugin=%s in path=%s", dPlugin->sharelib, ldSearchPath);
- goto OnErrorExit;
- }
-
- char *filename;
- char*fullpath;
- err = wrap_json_unpack(json_object_array_get_idx(pluginPathJ, 0), "{s:s, s:s !}", "fullpath", &fullpath, "filename", &filename);
- 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", fullpath, filename);
- }
-
- char pluginpath[CONTROL_MAXPATH_LEN];
- strncpy(pluginpath, fullpath, sizeof (pluginpath));
- strncat(pluginpath, "/", sizeof (pluginpath));
- strncat(pluginpath, filename, sizeof (pluginpath));
- dPlugin->dlHandle = dlopen(pluginpath, RTLD_NOW);
- if (!dPlugin->dlHandle) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:PLUGIN Fail to load pluginpath=%s err= %s", pluginpath, dlerror());
- goto OnErrorExit;
- }
-
- CtlPluginMagicT *ctlPluginMagic = (CtlPluginMagicT*) dlsym(dPlugin->dlHandle, "CtlPluginMagic");
- if (!ctlPluginMagic || ctlPluginMagic->magic != CTL_PLUGIN_MAGIC) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:Plugin symbol'CtlPluginMagic' missing or != CTL_PLUGIN_MAGIC plugin=%s", pluginpath);
- goto OnErrorExit;
- } else {
- AFB_NOTICE("DISPATCH-LOAD-CONFIG:Plugin %s successfully registered", ctlPluginMagic->label);
- }
-
- // Jose hack to make verbosity visible from sharelib
- struct afb_binding_data_v2 *afbHidenData = dlsym(dPlugin->dlHandle, "afbBindingV2data");
- if (afbHidenData) *afbHidenData = afbBindingV2data;
-
- // Push lua2cWrapper @ into plugin
- Lua2cWrapperT *lua2cInPlug = dlsym(dPlugin->dlHandle, "Lua2cWrap");
-#ifndef CONTROL_SUPPORT_LUA
- if (lua2cInPlug) *lua2cInPlug = NULL;
-#else
- // Lua2cWrapper is part of binder and not expose to dynamic link
- if (lua2cInPlug) *lua2cInPlug = DispatchOneL2c;
-
- {
- int Lua2cAddOne(luaL_Reg *l2cFunc, const char* l2cName, int index) {
- char funcName[CONTROL_MAXPATH_LEN];
- strncpy(funcName, "lua2c_", sizeof(funcName));
- strncat(funcName, l2cName, sizeof(funcName));
-
- Lua2cFunctionT l2cFunction= (Lua2cFunctionT)dlsym(dPlugin->dlHandle, funcName);
- if (!l2cFunction) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:Plugin symbol'%s' missing err=%s", funcName, dlerror());
- return 1;
- }
- l2cFunc[index].func=(void*)l2cFunction;
- l2cFunc[index].name=strdup(l2cName);
-
- return 0;
- }
-
- int errCount = 0;
- luaL_Reg *l2cFunc=NULL;
- int count=0;
-
- // look on l2c command and push them to LUA
- if (json_object_get_type(lua2csJ) == json_type_array) {
- int length = json_object_array_length(lua2csJ);
- l2cFunc = calloc(length + 1, sizeof (luaL_Reg));
- for (count=0; count < length; count++) {
- int err;
- const char *l2cName = json_object_get_string(json_object_array_get_idx(lua2csJ, count));
- err = Lua2cAddOne(l2cFunc, l2cName, count);
- if (err) errCount++;
- }
- } else {
- l2cFunc = calloc(2, sizeof (luaL_Reg));
- const char *l2cName = json_object_get_string(lua2csJ);
- errCount = Lua2cAddOne(l2cFunc, l2cName, 0);
- count=1;
- }
- if (errCount) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:Plugin %d symbols not found in plugin='%s'", errCount, pluginpath);
- goto OnErrorExit;
- } else {
- dPlugin->l2cFunc= l2cFunc;
- dPlugin->l2cCount= count;
- }
- }
-#endif
- DispatchPluginInstallCbT ctlPluginOnload = dlsym(dPlugin->dlHandle, "CtlPluginOnload");
- if (ctlPluginOnload) {
- dPlugin->context = (*ctlPluginOnload) (controlConfig->label, controlConfig->version, controlConfig->info);
- }
- }
-
- dispatchHandle->actions = DispatchLoadActions(controlConfig, actionsJ);
- if (!dispatchHandle->actions) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:ONLOAD Error when parsing actions %s", dispatchHandle->label);
- goto OnErrorExit;
- }
- return dispatchHandle;
-
-OnErrorExit:
- return NULL;
-}
-
-STATIC DispatchConfigT *DispatchLoadConfig(const char* filepath) {
- json_object *controlConfigJ, *ignoreJ;
- int err;
-
- // Load JSON file
- 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, *onloadsJ = NULL, *controlsJ = NULL, *eventsJ = NULL;
- err = wrap_json_unpack(controlConfigJ, "{s?o,so,s?o,s?o,s?o !}", "$schema", &ignoreJ, "metadata", &metadataJ, "onload", &onloadsJ, "controls", &controlsJ, "events", &eventsJ);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG Missing something metadata|[onload]|[controls]|[events] in %s", json_object_get_string(controlConfigJ));
- goto OnErrorExit;
- }
-
- DispatchConfigT *controlConfig = calloc(1, sizeof (DispatchConfigT));
- if (metadataJ) {
- err = wrap_json_unpack(metadataJ, "{ss,s?s,ss !}", "label", &controlConfig->label, "info", &controlConfig->info, "version", &controlConfig->version);
- if (err) {
- AFB_ERROR("DISPATCH-LOAD-CONFIG:METADATA Missing something label|version|[label] in %s", json_object_get_string(metadataJ));
- goto OnErrorExit;
- }
- }
-
- if (onloadsJ) {
- DispatchHandleT *dispatchHandle;
-
- if (json_object_get_type(onloadsJ) != json_type_array) {
- controlConfig->onloads = (DispatchHandleT**) calloc(2, sizeof (void*));
- dispatchHandle = DispatchLoadOnload(controlConfig, onloadsJ);
- controlConfig->onloads[0] = dispatchHandle;
- } else {
- int length = json_object_array_length(onloadsJ);
- controlConfig->onloads = (DispatchHandleT**) calloc(length + 1, sizeof (void*));
-
- for (int jdx = 0; jdx < length; jdx++) {
- json_object *onloadJ = json_object_array_get_idx(onloadsJ, jdx);
- dispatchHandle = DispatchLoadOnload(controlConfig, onloadJ);
- controlConfig->onloads[jdx] = dispatchHandle;
- }
- }
- }
-
- if (controlsJ) {
- DispatchHandleT *dispatchHandle;
-
- if (json_object_get_type(controlsJ) != json_type_array) {
- controlConfig->controls = (DispatchHandleT**) calloc(2, sizeof (void*));
- dispatchHandle = DispatchLoadControl(controlConfig, controlsJ);
- controlConfig->controls[0] = dispatchHandle;
- } else {
- int length = json_object_array_length(controlsJ);
- controlConfig->controls = (DispatchHandleT**) calloc(length + 1, sizeof (void*));
-
- for (int jdx = 0; jdx < length; jdx++) {
- json_object *controlJ = json_object_array_get_idx(controlsJ, jdx);
- dispatchHandle = DispatchLoadControl(controlConfig, controlJ);
- controlConfig->controls[jdx] = dispatchHandle;
- }
- }
- }
-
- if (eventsJ) {
- DispatchHandleT *dispatchHandle;
-
- if (json_object_get_type(eventsJ) != json_type_array) {
- controlConfig->events = (DispatchHandleT**) calloc(2, sizeof (void*));
- dispatchHandle = DispatchLoadControl(controlConfig, eventsJ);
- controlConfig->events[0] = dispatchHandle;
- } else {
- int length = json_object_array_length(eventsJ);
- controlConfig->events = (DispatchHandleT**) calloc(length + 1, sizeof (void*));
-
- for (int jdx = 0; jdx < length; jdx++) {
- json_object *eventJ = json_object_array_get_idx(eventsJ, jdx);
- dispatchHandle = DispatchLoadControl(controlConfig, eventJ);
- controlConfig->events[jdx] = dispatchHandle;
- }
- }
- }
-
- return controlConfig;
-
-OnErrorExit:
- return NULL;
-}
-
-
-// Load default config file at init
-
-PUBLIC int DispatchInit() {
- int index, err, luaLoaded = 0;
- char controlFile [CONTROL_MAXPATH_LEN];
-
- const char *dirList= getenv("CONTROL_CONFIG_PATH");
- if (!dirList) dirList=CONTROL_CONFIG_PATH;
-
- strncpy(controlFile, CONTROL_CONFIG_PRE "-", CONTROL_MAXPATH_LEN);
- strncat(controlFile, GetBinderName(), CONTROL_MAXPATH_LEN);
-
- // search for default dispatch config file
- json_object* responseJ = ScanForConfig(dirList, CTL_SCAN_RECURSIVE, controlFile, "json");
-
- // We load 1st file others are just warnings
- for (index = 0; index < json_object_array_length(responseJ); index++) {
- json_object *entryJ = json_object_array_get_idx(responseJ, index);
-
- char *filename;
- char*fullpath;
- err = wrap_json_unpack(entryJ, "{s:s, s:s !}", "fullpath", &fullpath, "filename", &filename);
- if (err) {
- AFB_ERROR("DISPATCH-INIT HOOPs invalid JSON entry= %s", json_object_get_string(entryJ));
- goto OnErrorExit;
- }
-
- if (index == 0) {
- if (strcasestr(filename, controlFile)) {
- char filepath[CONTROL_MAXPATH_LEN];
- strncpy(filepath, fullpath, sizeof (filepath));
- strncat(filepath, "/", sizeof (filepath));
- strncat(filepath, filename, sizeof (filepath));
- configHandle = DispatchLoadConfig(filepath);
- if (!configHandle) {
- AFB_ERROR("DISPATCH-INIT:ERROR Fail loading [%s]", filepath);
- goto OnErrorExit;
- }
- luaLoaded = 1;
- break;
- }
- } else {
- AFB_WARNING("DISPATCH-INIT:WARNING Secondary Control Config Ignored %s/%s", fullpath, filename);
- }
- }
-
- // no dispatch config found remove control API from binder
- if (!luaLoaded) {
- AFB_WARNING("DISPATCH-INIT:WARNING (setenv CONTROL_CONFIG_PATH) No Config '%s-*.json' in '%s'", controlFile, dirList);
- }
-
- 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/Controller-afb/ctl-lua.c b/Controller-afb/ctl-lua.c
deleted file mode 100644
index 8d5a87e..0000000
--- a/Controller-afb/ctl-lua.c
+++ /dev/null
@@ -1,1068 +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:
- * (manual) https://www.lua.org/manual/5.3/manual.html
- * (lua->C) http://www.troubleshooters.com/codecorn/lua/lua_c_calls_lua.htm#_Anatomy_of_a_Lua_Call
- * (lua/C Var) http://acamara.es/blog/2012/08/passing-variables-from-lua-5-2-to-c-and-vice-versa/
- * (Lua/C Lib)https://john.nachtimwald.com/2014/07/12/wrapping-a-c-library-in-lua/
- * (Lua/C Table) https://gist.github.com/SONIC3D/10388137
- * (Lua/C Nested table) https://stackoverflow.com/questions/45699144/lua-nested-table-from-lua-to-c
- * (Lua/C Wrapper) https://stackoverflow.com/questions/45699950/lua-passing-handle-to-function-created-with-newlib
- *
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.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 512
-#define JSON_ERROR (json_object*)-1
-static afb_req NULL_AFBREQ = {};
-
-
-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;
- void *handle;
- char *info;
-} LuaAfbContextT;
-
-typedef struct {
- const char *callback;
- json_object *context;
- void *handle;
-} 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, void *handle, 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;
- afbContext->handle= handle;
- return afbContext;
-}
-
-STATIC void LuaCtxFree (LuaAfbContextT *afbContext) {
- free(afbContext->info);
- free(afbContext);
-}
-
-// 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 *LuaPopOneArg (lua_State* luaState, int idx);
-
-// Move a table from Internal Lua representation to Json one
-// Numeric table are transformed in json array, string one in object
-// Mix numeric/string key are not supported
-STATIC json_object *LuaTableToJson (lua_State* luaState, int index) {
- #define LUA_KEY_INDEX -2
- #define LUA_VALUE_INDEX -1
-
- int idx;
- int tableType;
- json_object *tableJ= NULL;
-
- lua_pushnil(luaState); // 1st key
- if (index < 0) index--;
- for (idx=1; lua_next(luaState, index) != 0; idx++) {
-
- // uses 'key' (at index -2) and 'value' (at index -1)
- if (lua_type(luaState,LUA_KEY_INDEX) == LUA_TSTRING) {
-
- if (!tableJ) {
- tableJ= json_object_new_object();
- tableType=LUA_TSTRING;
- } else if (tableType != LUA_TSTRING){
- AFB_ERROR("MIX Lua Table with key string/numeric not supported");
- return NULL;
- }
-
- const char *key= lua_tostring(luaState, LUA_KEY_INDEX);
- json_object *argJ= LuaPopOneArg(luaState, LUA_VALUE_INDEX);
- json_object_object_add(tableJ, key, argJ);
-
- } else {
- if (!tableJ) {
- tableJ= json_object_new_array();
- tableType=LUA_TNUMBER;
- } else if(tableType != LUA_TNUMBER) {
- AFB_ERROR("MIX Lua Table with key numeric/string not supported");
- return NULL;
- }
-
- json_object *argJ= LuaPopOneArg(luaState, LUA_VALUE_INDEX);
- json_object_array_add(tableJ, 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 *LuaPopOneArg (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:
- value= LuaTableToJson(luaState, idx);
- break;
- case LUA_TNIL:
- value=json_object_new_string("nil") ;
- break;
- case LUA_TUSERDATA:
- value=json_object_new_int64((int64_t)lua_touserdata(luaState, idx)); // store userdata as int !!!
- break;
-
- default:
- AFB_NOTICE ("LuaPopOneArg: 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=LuaPopOneArg (luaState, start);
- } else {
- // loop on remaining return arguments
- responseJ= json_object_new_array();
- for (int idx=start; idx <= stop; idx++) {
- json_object *argJ=LuaPopOneArg (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 {
- if (targetIdx >= LUA_MSG_MAX_LENGTH) {
- AFB_WARNING ("LuaFormatMessage: message[%s] owerverflow LUA_MSG_MAX_LENGTH=%d", format, LUA_MSG_MAX_LENGTH);
- targetIdx --; // move backward for EOL
- break;
- } else {
- message[targetIdx++] = format[idx];
- }
- }
- }
- message[targetIdx]='\0';
-
-PrintMessage:
- switch (action) {
- case AFB_MSG_WARNING:
- AFB_WARNING ("%s", message);
- break;
- case AFB_MSG_NOTICE:
- AFB_NOTICE ("%s", message);
- break;
- case AFB_MSG_DEBUG:
- AFB_DEBUG ("%s", message);
- break;
- case AFB_MSG_INFO:
- AFB_INFO ("%s", message);
- break;
- case AFB_MSG_ERROR:
- default:
- AFB_ERROR ("%s", 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) );
- }
-
- free (contextCB);
-}
-
-
-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 LuaAfbEventPush(lua_State* luaState) {
- LuaAfbEvent *afbevt;
- int index;
-
- // if no private event handle then use default binding event
- if (lua_islightuserdata(luaState, LUA_FIST_ARG)) {
- afbevt = (LuaAfbEvent*) lua_touserdata(luaState, LUA_FIST_ARG);
- index=LUA_FIST_ARG+1;
- } else {
- index=LUA_FIST_ARG;
- afbevt=luaDefaultEvt;
- }
-
- if (!afb_event_is_valid(afbevt->event)) {
- lua_pushliteral (luaState, "LuaAfbMakePush-Fail invalid event");
- goto OnErrorExit;
- }
-
- json_object *ctlEventJ= LuaTableToJson(luaState, index);
- if (!ctlEventJ) {
- lua_pushliteral (luaState, "LuaAfbEventPush-Syntax is AFB:signal ([evtHandle], {lua table})");
- goto OnErrorExit;
- }
-
- int done = afb_event_push(afbevt->event, ctlEventJ);
- if (!done) {
- lua_pushliteral (luaState, "LuaAfbEventPush-Fail No Subscriber to event");
- AFB_ERROR ("LuaAfbEventPush-Fail name subscriber event=%s count=%d", afbevt->name, afbevt->count);
- goto OnErrorExit;
- }
- afbevt->count++;
- return 0;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbEventSubscribe(lua_State* luaState) {
- LuaAfbEvent *afbevt;
-
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIST_ARG);
- if (!afbContext) {
- lua_pushliteral (luaState, "LuaAfbEventSubscribe-Fail Invalid request handle");
- goto OnErrorExit;
- }
-
- // if no private event handle then use default binding event
- if (lua_islightuserdata(luaState, LUA_FIST_ARG+1)) {
- afbevt = (LuaAfbEvent*) lua_touserdata(luaState, LUA_FIST_ARG+1);
- } else {
- afbevt=luaDefaultEvt;
- }
-
- if (!afb_event_is_valid(afbevt->event)) {
- lua_pushliteral (luaState, "LuaAfbMakePush-Fail invalid event handle");
- goto OnErrorExit;
- }
-
- int err = afb_req_subscribe(afbContext->request, afbevt->event);
- if (err) {
- lua_pushliteral (luaState, "LuaAfbEventSubscribe-Fail No Subscriber to event");
- AFB_ERROR ("LuaAfbEventPush-Fail name subscriber event=%s count=%d", afbevt->name, afbevt->count);
- goto OnErrorExit;
- }
- afbevt->count++;
- return 0;
-
- OnErrorExit:
- lua_error(luaState);
- return 1;
-}
-
-STATIC int LuaAfbEventMake(lua_State* luaState) {
- int count = lua_gettop(luaState);
- LuaAfbEvent *afbevt=calloc(1,sizeof(LuaAfbEvent));
-
- if (count != LUA_FIST_ARG || !lua_isstring(luaState, LUA_FIST_ARG)) {
- lua_pushliteral (luaState, "LuaAfbEventMake-Syntax is evtHandle= AFB:event ('myEventName')");
- goto OnErrorExit;
- }
-
- // event name should be the only argument
- afbevt->name= strdup (lua_tostring(luaState,LUA_FIST_ARG));
-
- // create a new binder event
- afbevt->event = afb_daemon_make_event(afbevt->name);
- if (!afb_event_is_valid(afbevt->event)) {
- lua_pushliteral (luaState, "LuaAfbEventMake-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;
-}
-
-// Function call from LUA when lua2c plugin L2C is used
-PUBLIC int Lua2cWrapper(lua_State* luaState, char *funcname, Lua2cFunctionT callback, void *context) {
-
- json_object *argsJ= LuaPopArgs(luaState, LUA_FIST_ARG+1);
- int response = (*callback) (funcname, argsJ, context);
-
- // push response to LUA
- lua_pushinteger(luaState, response);
- return 1;
-}
-
-// Generated some fake event based on watchdog/counter
-PUBLIC int LuaCallFunc (DispatchSourceT source, 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 source on the stack
- count=1;
- lua_pushinteger(luaState, source);
-
- // push argsJ on the stack
- 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;
-
- 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,NULL,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 !}", "target", &func, "args", &argsJ);
- if (err) {
- AFB_ERROR ("LUA-DOCALL-SYNTAX missing target|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, NULL, 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
- char *filename; char*fullpath;
- char luaScriptPath[CONTROL_MAXPATH_LEN];
- int index;
-
- // scan luascript search path once
- static json_object *luaScriptPathJ =NULL;
-
- // extract value from query
- const char *target=NULL,*func=NULL;
- json_object *argsJ=NULL;
- err= wrap_json_unpack (queryJ, "{s:s,s?s,s?s,s?o !}","target", &target,"path",&luaScriptPathJ,"function",&func,"args",&argsJ);
- if (err) {
- AFB_ERROR ("LUA-DOSCRIPT-SYNTAX:missing target|[path]|[function]|[args] query=%s", json_object_get_string(queryJ));
- goto OnErrorExit;
- }
-
- // search for filename=script in CONTROL_LUA_PATH
- if (!luaScriptPathJ) {
- strncpy(luaScriptPath,CONTROL_DOSCRIPT_PRE, sizeof(luaScriptPath));
- strncat(luaScriptPath,"-", sizeof(luaScriptPath));
- strncat(luaScriptPath,target, sizeof(luaScriptPath));
- luaScriptPathJ= ScanForConfig(CONTROL_LUA_PATH , CTL_SCAN_RECURSIVE,luaScriptPath,".lua");
- }
- 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 (index > 0) AFB_WARNING("LUA-DOSCRIPT-SCAN:Ignore second script=%s path=%s", filename, fullpath);
- else {
- strncpy (luaScriptPath, fullpath, sizeof(luaScriptPath));
- strncat (luaScriptPath, "/", sizeof(luaScriptPath));
- strncat (luaScriptPath, filename, sizeof(luaScriptPath));
- }
- }
-
- err= luaL_loadfile(luaState, luaScriptPath);
- if (err) {
- AFB_ERROR ("LUA-DOSCRIPT HOOPs Error in LUA loading scripts=%s err=%s", luaScriptPath, lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
-
- // 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))!=NULL) {
- strncpy(luaScriptPath,"_", sizeof(luaScriptPath));
- strncat(luaScriptPath,func, sizeof(luaScriptPath));
- func=luaScriptPath;
- }
- 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, NULL, 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_execlua (afb_req request) {
- LuaDoAction (LUA_DOSTRING, request);
-}
-
-PUBLIC void ctlapi_request (afb_req request) {
- LuaDoAction (LUA_DOCALL, request);
-}
-
-PUBLIC void ctlapi_debuglua (afb_req request) {
- LuaDoAction (LUA_DOSCRIPT, request);
-}
-
-STATIC int LuaTimerClear (lua_State* luaState) {
-
- // Get Timer Handle
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIST_ARG);
- if (!afbContext) goto OnErrorExit;
-
- // retrieve useful information opaque handle
- TimerHandleT *timerHandle = (TimerHandleT*)afbContext->handle;
-
- AFB_NOTICE ("LuaTimerClear timer=%s", timerHandle->label);
- TimerEvtStop(timerHandle);
-
- return 0; //happy end
-
-OnErrorExit:
- return 1;
-}
-STATIC int LuaTimerGet (lua_State* luaState) {
-
- // Get Timer Handle
- LuaAfbContextT *afbContext= LuaCtxCheck(luaState, LUA_FIST_ARG);
- if (!afbContext) goto OnErrorExit;
-
- // retrieve useful information opaque handle
- TimerHandleT *timerHandle = (TimerHandleT*)afbContext->handle;
-
- // create response as a JSON object
- json_object *responseJ= json_object_new_object();
- json_object_object_add(responseJ,"label", json_object_new_string(timerHandle->label));
- json_object_object_add(responseJ,"delay", json_object_new_int(timerHandle->delay));
- json_object_object_add(responseJ,"count", json_object_new_int(timerHandle->count));
-
- // return JSON object as Lua table
- int count=LuaPushArgument(responseJ);
-
- // free json object
- json_object_put(responseJ);
-
- return count; // return argument
-
-OnErrorExit:
- return 0;
-}
-
-// Timer Callback
-
-// Set timer
-STATIC int LuaTimerSetCB (void *handle) {
- LuaCallServiceT *contextCB =(LuaCallServiceT*) handle;
- TimerHandleT *timerHandle = (TimerHandleT*) contextCB->handle;
- int count;
-
- // push timer handle and user context on Lua stack
- lua_getglobal(luaState, contextCB->callback);
-
- // Push timer handle
- LuaAfbContextT *afbContext= LuaCtxPush(luaState, NULL_AFBREQ, contextCB->handle, timerHandle->label);
- if (!afbContext) goto OnErrorExit;
- count=1;
-
- // Push user Context
- count+= LuaPushArgument(contextCB->context);
-
- int err=lua_pcall(luaState, count, LUA_MULTRET, 0);
- if (err) {
- AFB_ERROR ("LUA-TIMER-CB:FAIL response=%s err=%s", json_object_get_string(contextCB->context), lua_tostring(luaState,-1));
- goto OnErrorExit;
- }
-
- // get return parameter
- if (!lua_isboolean(luaState, -1)) {
- return (lua_toboolean(luaState, -1));
- }
-
- // timer last run free context resource
- if (timerHandle->count == 1) {
- LuaCtxFree(afbContext);
- }
- return 0; // By default we are happy
-
- OnErrorExit:
- return 1; // stop timer
-}
-
-STATIC int LuaTimerSet(lua_State* luaState) {
- const char *label=NULL, *info=NULL;
- int delay=0, count=0;
-
- json_object *timerJ = LuaPopOneArg(luaState, LUA_FIST_ARG);
- const char *callback = lua_tostring(luaState, LUA_FIST_ARG + 1);
- json_object *contextJ = LuaPopOneArg(luaState, LUA_FIST_ARG + 2);
-
- if (lua_gettop(luaState) != LUA_FIST_ARG+2 || !timerJ || !callback || !contextJ) {
- lua_pushliteral(luaState, "LuaTimerSet-Syntax timerset (timerT, 'callback', contextT)");
- goto OnErrorExit;
- }
-
- int err = wrap_json_unpack(timerJ, "{ss, s?s si, si !}", "label", &label, "info", &info, "delay", &delay, "count", &count);
- if (err) {
- lua_pushliteral(luaState, "LuaTimerSet-Syntax timerT={label:xxx delay:ms, count:xx}");
- goto OnErrorExit;
- }
-
- // everything look fine create timer structure
- TimerHandleT *timerHandle = malloc (sizeof (TimerHandleT));
- timerHandle->delay=delay;
- timerHandle->count=count;
- timerHandle->label=label;
-
- // Allocate handle to store context and callback
- LuaCallServiceT *contextCB = calloc (1, sizeof(LuaCallServiceT));
- contextCB->callback= callback;
- contextCB->context = contextJ;
- contextCB->handle = timerHandle;
-
- // fire timer
- TimerEvtStart (timerHandle, LuaTimerSetCB, contextCB);
-
- return 0; // Happy No Return Function
-
-OnErrorExit:
- lua_error(luaState);
- return 1; // return error code
-}
-
-// Register a new L2c list of LUA user plugin commands
-PUBLIC void LuaL2cNewLib(const char *label, luaL_Reg *l2cFunc, int count) {
- // luaL_newlib(luaState, l2cFunc); macro does not work with pointer :(
- luaL_checkversion(luaState);
- lua_createtable(luaState, 0, count+1);
- luaL_setfuncs(luaState,l2cFunc,0);
- lua_setglobal(luaState, label);
-}
-
-static const luaL_Reg afbFunction[] = {
- {"timerclear", LuaTimerClear},
- {"timerget" , LuaTimerGet},
- {"timerset" , LuaTimerSet},
- {"notice" , LuaPrintNotice},
- {"info" , LuaPrintInfo},
- {"warning" , LuaPrintWarning},
- {"debug" , LuaPrintDebug},
- {"error" , LuaPrintError},
- {"servsync" , LuaAfbServiceSync},
- {"service" , LuaAfbService},
- {"success" , LuaAfbSuccess},
- {"fail" , LuaAfbFail},
- {"subscribe" , LuaAfbEventSubscribe},
- {"evtmake" , LuaAfbEventMake},
- {"evtpush" , LuaAfbEventPush},
-
- {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, GetBinderName(), sizeof(fullprefix));
- strncat (fullprefix, "-", sizeof(fullprefix));
-
- const char *dirList= getenv("CONTROL_LUA_PATH");
- if (!dirList) dirList=CONTROL_LUA_PATH;
-
- json_object *luaScriptPathJ = ScanForConfig(dirList , 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 (setenv CONTROL_LUA_PATH) No LUA '%s*.lua' in '%s'", fullprefix, dirList);
- }
-
- AFB_DEBUG ("Audio control-LUA Init Done");
- return 0;
-
- OnErrorExit:
- return 1;
-}
diff --git a/Controller-afb/ctl-plugin-sample.c b/Controller-afb/ctl-plugin-sample.c
deleted file mode 100644
index 1d66802..0000000
--- a/Controller-afb/ctl-plugin-sample.c
+++ /dev/null
@@ -1,134 +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.
- *
- * 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;
-}
-
-// Declare this sharelib as a Controller Plugin
-CTLP_REGISTER("MyCtlSamplePlugin");
-
-// Call at initialisation time
-PUBLIC CTLP_ONLOAD(label, version, info) {
- MyPluginCtxT *pluginCtx= (MyPluginCtxT*)calloc (1, sizeof(MyPluginCtxT));
- pluginCtx->magic = MY_PLUGIN_MAGIC;
- pluginCtx->count = -1;
-
- AFB_NOTICE ("CONTROLLER-PLUGIN-SAMPLE:Onload label=%s version=%s info=%s", label, info, version);
- return (void*)pluginCtx;
-}
-
-PUBLIC CTLP_CAPI (SamplePolicyInit, source, label, argsJ, queryJ, context) {
- MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context;
- if (!context || pluginCtx->magic != MY_PLUGIN_MAGIC) {
- AFB_ERROR("CONTROLLER-PLUGIN-SAMPLE:SamplePolicyInit (Hoops) Invalid Sample Plugin Context");
- return -1;
- };
-
- pluginCtx->count = 0;
- AFB_NOTICE ("CONTROLLER-PLUGIN-SAMPLE:Init label=%s args=%s\n", label, jsonToString(argsJ));
- return 0;
-}
-
-PUBLIC CTLP_CAPI (sampleControlMultimedia, source, label, argsJ,queryJ,context) {
- MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context;
-
- if (!context || pluginCtx->magic != MY_PLUGIN_MAGIC) {
- AFB_ERROR("CONTROLLER-PLUGIN-SAMPLE:sampleControlMultimedia (Hoops) Invalid Sample Plugin Context");
- return -1;
- };
- pluginCtx->count++;
- AFB_NOTICE ("CONTROLLER-PLUGIN-SAMPLE:sampleControlMultimedia SamplePolicyCount action=%s args=%s query=%s count=%d"
- , label, jsonToString(argsJ), jsonToString(queryJ), pluginCtx->count);
- return 0;
-}
-
-PUBLIC CTLP_CAPI (sampleControlNavigation, source, label, argsJ, queryJ, context) {
- MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context;
-
- if (!context || pluginCtx->magic != MY_PLUGIN_MAGIC) {
- AFB_ERROR("CONTROLLER-PLUGIN-SAMPLE:sampleControlNavigation (Hoops) Invalid Sample Plugin Context");
- return -1;
- };
- pluginCtx->count++;
- AFB_NOTICE ("CONTROLLER-PLUGIN-SAMPLE:sampleControlNavigation SamplePolicyCount action=%s args=%s query=%s count=%d"
- ,label, jsonToString(argsJ), jsonToString(queryJ), pluginCtx->count);
- return 0;
-}
-
-PUBLIC CTLP_CAPI (SampleControlEvent, source, label, argsJ, queryJ, context) {
- MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context;
-
- if (!context || pluginCtx->magic != MY_PLUGIN_MAGIC) {
- AFB_ERROR("CONTROLLER-PLUGIN-SAMPLE:cousampleControlMultimediant (Hoops) Invalid Sample Plugin Context");
- return -1;
- };
- pluginCtx->count++;
- AFB_NOTICE ("CONTROLLER-PLUGIN-SAMPLE:sampleControlMultimedia SamplePolicyCount action=%s args=%s query=%s count=%d"
- ,label, jsonToString(argsJ), jsonToString(queryJ), pluginCtx->count);
- return 0;
-}
-
-// This function is a LUA function. Lua2CHelloWorld label should be declare in the "onload" section of JSON config file
-PUBLIC CTLP_LUA2C (Lua2cHelloWorld1, label, argsJ, context) {
- MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context;
-
- if (!context || pluginCtx->magic != MY_PLUGIN_MAGIC) {
- AFB_ERROR("CONTROLLER-PLUGIN-SAMPLE:Lua2cHelloWorld1 (Hoops) Invalid Sample Plugin Context");
- return -1;
- };
- pluginCtx->count++;
- AFB_NOTICE ("CONTROLLER-PLUGIN-SAMPLE:Lua2cHelloWorld1 SamplePolicyCount action=%s args=%s count=%d"
- ,label, jsonToString(argsJ), pluginCtx->count);
- return 0;
-}
-
-// This function is a LUA function. Lua2CHelloWorld label should be declare in the "onload" section of JSON config file
-PUBLIC CTLP_LUA2C (Lua2cHelloWorld2, label, argsJ, context) {
- MyPluginCtxT *pluginCtx= (MyPluginCtxT*)context;
-
- if (!context || pluginCtx->magic != MY_PLUGIN_MAGIC) {
- AFB_ERROR("CONTROLLER-PLUGIN-SAMPLE:Lua2cHelloWorld2 (Hoops) Invalid Sample Plugin Context");
- return -1;
- };
- pluginCtx->count++;
- AFB_NOTICE ("CONTROLLER-PLUGIN-SAMPLE:Lua2cHelloWorld2 SamplePolicyCount action=%s args=%s count=%d"
- ,label, jsonToString(argsJ), pluginCtx->count);
- return 0;
-}
diff --git a/Controller-afb/ctl-policy.c b/Controller-afb/ctl-policy.c
deleted file mode 100644
index e9798b3..0000000
--- a/Controller-afb/ctl-policy.c
+++ /dev/null
@@ -1,221 +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 <dirent.h>
-#include <json-c/json_object.h>
-
-#include "wrap-json.h"
-#include "ctl-binding.h"
-
-STATIC PolicyCtlConfigT *ctlHandle = NULL;
-
-// List Avaliable Configuration Files
-STATIC json_object* ScanForConfig (char* searchPath) {
- json_object *responseJ;
- DIR *dirHandle;
- char *dirPath;
- char* dirList= strdup(searchPath);
-
- responseJ = json_object_new_array();
- for (dirPath= strtok(dirList, ":"); dirPath && *dirPath; dirPath=strtok(NULL,":")) {
- struct dirent *dirEnt;
-
- dirHandle = opendir (dirPath);
- if (!dirHandle) {
- AFB_NOTICE ("CONFIG-SCANNING dir=%s not readable", dirPath);
- continue;
- }
-
- AFB_NOTICE ("CONFIG-SCANNING:ctl_listconfig scanning: %s", dirPath);
- while ((dirEnt = readdir(dirHandle)) != NULL) {
- // Unknown type is accepted to support dump filesystems
- if (dirEnt->d_type == DT_REG || dirEnt->d_type == DT_UNKNOWN) {
- 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);
- }
- }
- }
-
- free (dirList);
- return (responseJ);
-}
-
-PUBLIC void ctlapi_authorize (PolicyCtlEnumT control, afb_req request) {
- json_object*tmpJ;
-
- json_object* queryJ= afb_req_json(request);
- int done=json_object_object_get_ex(queryJ, "closing", &tmpJ);
- if (done) return;
-
-}
-
-
-// List Avaliable Configuration Files
-PUBLIC void ctlapi_config (struct afb_req request) {
- json_object*tmpJ;
- char *dirList;
-
- json_object* queryJ = afb_req_json(request);
- if (queryJ && json_object_object_get_ex (queryJ, "cfgpath" , &tmpJ)) {
- dirList = strdup (json_object_get_string(tmpJ));
- } else {
- dirList = strdup (CONTROL_CONFIG_PATH);
- AFB_NOTICE ("CONFIG-MISSING: use default CONTROL_CONFIG_PATH=%s", CONTROL_CONFIG_PATH);
- }
-
- // get list of config file
- struct json_object *responseJ = ScanForConfig(dirList);
-
- if (json_object_array_length(responseJ) == 0) {
- afb_req_fail(request, "CONFIGPATH:EMPTY", "No Config Found in CONTROL_CONFIG_PATH");
- } else {
- afb_req_success(request, responseJ, NULL);
- }
-
- return;
-}
-
-STATIC PolicyActionT **PolicyLoadActions (json_object *actionsJ) {
- int err;
- PolicyActionT ** actions;
-
- // unpack individual action object
- int actionUnpack (json_object *actionJ, PolicyActionT *action) {
-
- err= wrap_json_unpack(actionJ, "{ss,s?s,s?s,s?s,s?s,s?s !}"
- , "label",&action->label, "info",&action->info, "callback",&action->callback, "query",&queryJ, "api",&action->api, "verb", &action->verb);
- if (err) {
- AFB_ERROR ("POLICY-LOAD-ACTION Missing something label|info|callback|api|verb|query in %s", json_object_get_string(actionJ));
- return -1;
- }
- if (!action->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 policyControl;
-
-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_CONFIG_PATH);
-
- 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_CONFIG_FILE)) {
- char filepath[255];
- strncpy(filepath, dirpath, sizeof(filepath));
- strncat(filepath, "/", sizeof(filepath));
- strncat(filepath, filename, sizeof(filepath));
- ctlHandle = PolicyLoadConfig (filepath);
- if (!ctlHandle) goto OnErrorExit;
- break;
- }
- }
-
- // no policy config found remove control API from binder
- if (index == 0) goto OnErrorExit;
-
- AFB_NOTICE ("SUCCES: Audio Control Policy Init");
- return 0;
-
-OnErrorExit:
- AFB_NOTICE ("ERROR: Audio Control Policy Init");
- return 1;
-}
-
-
-
diff --git a/Controller-afb/ctl-timer.c b/Controller-afb/ctl-timer.c
deleted file mode 100644
index a826f9f..0000000
--- a/Controller-afb/ctl-timer.c
+++ /dev/null
@@ -1,101 +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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <systemd/sd-event.h>
-
-#include "ctl-binding.h"
-
-#define DEFAULT_PAUSE_DELAY 3000
-#define DEFAULT_TEST_COUNT 1
-typedef struct {
- int value;
- const char *label;
-} AutoTestCtxT;
-
-static afb_event afbevt;
-
-STATIC int TimerNext (sd_event_source* source, uint64_t timer, void* handle) {
- TimerHandleT *timerHandle = (TimerHandleT*) handle;
- int done;
- uint64_t usec;
-
- // Rearm timer if needed
- timerHandle->count --;
- if (timerHandle->count == 0) {
- sd_event_source_unref(source);
- free (handle);
- return 0;
- }
- else {
- // otherwise validate timer for a new run
- sd_event_now(afb_daemon_get_event_loop(), CLOCK_MONOTONIC, &usec);
- sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
- sd_event_source_set_time(source, usec + timerHandle->delay*1000);
- }
-
- done= timerHandle->callback(timerHandle->context);
- if (!done) goto OnErrorExit;
-
- return 0;
-
-OnErrorExit:
- AFB_WARNING("TimerNext Callback Fail Tag=%s", timerHandle->label);
- return -1;
-}
-
-PUBLIC void TimerEvtStop(TimerHandleT *timerHandle) {
-
- sd_event_source_unref(timerHandle->evtSource);
- free (timerHandle);
-}
-
-
-PUBLIC void TimerEvtStart(TimerHandleT *timerHandle, timerCallbackT callback, void *context) {
- uint64_t usec;
-
- // populate CB handle
- timerHandle->callback=callback;
- timerHandle->context=context;
-
- // set a timer with ~250us accuracy
- sd_event_now(afb_daemon_get_event_loop(), CLOCK_MONOTONIC, &usec);
- sd_event_add_time(afb_daemon_get_event_loop(), &timerHandle->evtSource, CLOCK_MONOTONIC, usec+timerHandle->delay*1000, 250, TimerNext, timerHandle);
-}
-
-PUBLIC afb_event TimerEvtGet(void) {
- return afbevt;
-}
-
-
-// Create Binding Event at Init
-PUBLIC int TimerEvtInit () {
-
- // create binder event to send test pause/resume
- afbevt = afb_daemon_make_event("control");
- if (!afb_event_is_valid(afbevt)) {
- AFB_ERROR ("POLCTL_INIT: Cannot register ctl-events");
- return 1;
- }
-
- AFB_DEBUG ("Audio Control-Events Init Done");
- return 0;
-}
-
diff --git a/afb-utilities b/afb-utilities
new file mode 160000
+Subproject 1860c197a402f76f960eb2e373daf1259592cb6
diff --git a/conf.d/CMakeLists.txt b/conf.d/CMakeLists.txt
deleted file mode 100644
index 28a0609..0000000
--- a/conf.d/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-###########################################################################
-# Copyright 2015, 2016, 2017 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.
-###########################################################################
-
-
-# Include any directory not starting with _
-# -----------------------------------------------------
-PROJECT_SUBDIRS_ADD(${PROJECT_SRC_DIR_PATTERN})
diff --git a/conf.d/cmake/00-debian-config.cmake b/conf.d/cmake/00-debian-config.cmake
deleted file mode 100644
index 466c4de..0000000
--- a/conf.d/cmake/00-debian-config.cmake
+++ /dev/null
@@ -1 +0,0 @@
-add_required_module(lua-5.3 REQUIRED lua-5.3>=5.3)
diff --git a/conf.d/cmake/00-fedora-config.cmake b/conf.d/cmake/00-fedora-config.cmake
deleted file mode 100644
index 7b4a99a..0000000
--- a/conf.d/cmake/00-fedora-config.cmake
+++ /dev/null
@@ -1 +0,0 @@
-add_required_module(lua REQUIRED lua>=5.3)
diff --git a/conf.d/cmake/00-suse-config.cmake b/conf.d/cmake/00-suse-config.cmake
deleted file mode 100644
index 7b4a99a..0000000
--- a/conf.d/cmake/00-suse-config.cmake
+++ /dev/null
@@ -1 +0,0 @@
-add_required_module(lua REQUIRED lua>=5.3)
diff --git a/conf.d/cmake/config.cmake b/conf.d/cmake/config.cmake
index d5607e9..fd2dd40 100644
--- a/conf.d/cmake/config.cmake
+++ b/conf.d/cmake/config.cmake
@@ -62,14 +62,6 @@ set (PKG_REQUIRED_LIST
libafbwsc
)
-# Controller project needed variables.
-# Compilation options specific to that target set
-# in the CMakeLists.txt of that target to correctly
-# expand variables.
-# ----------------------------------------------------
-set (CTL_PLUGIN_PRE "ctl-" CACHE STRING "Prefix for Controller share plugin")
-set (CTL_PLUGIN_EXT ".ctlso" CACHE STRING "Postfix for Controller share plugin")
-
# Compilation options definition
# Use CMake generator expressions to specify only for a specific language
# Values are prefilled with default options that is currently used.
diff --git a/conf.d/project/json.d/CMakeLists.txt b/conf.d/project/json.d/CMakeLists.txt
deleted file mode 100644
index 8070997..0000000
--- a/conf.d/project/json.d/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-###########################################################################
-# Copyright 2017 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.
-###########################################################################
-
-
-##################################################
-# Control Policy Config file
-##################################################
-PROJECT_TARGET_ADD(ctl-config.d)
-
- file(GLOB XML_FILES "*.json")
-
- add_input_files("${XML_FILES}")
-
- SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
- LABELS "DATA"
- OUTPUT_NAME ${TARGET_NAME}
- )
diff --git a/conf.d/project/json.d/onload-audio-control.json b/conf.d/project/json.d/onload-audio-control.json
deleted file mode 100644
index 77a8fce..0000000
--- a/conf.d/project/json.d/onload-audio-control.json
+++ /dev/null
@@ -1,128 +0,0 @@
-{
- "$schema": "ToBeDone",
- "metadata": {
- "label": "sample-audio-control",
- "info": "Provide Default Audio Policy for Multimedia, Navigation and Emergency",
- "version": "1.0"
- },
- "onload": [{
- "label": "onload-default",
- "info": "onload initialisation config",
- "plugin": {
- "label" : "_MyPlug",
- "sharelib": "ctl-audio-plugin-sample.ctlso",
- "lua2c": ["Lua2cHelloWorld1", "Lua2cHelloWorld2"]
- },
- "require": ["intel-hda", "jabra-usb", "scarlett-usb"],
- "actions": [
- {
- "label": "onload-sample-cb",
- "info": "Call control sharelib install entrypoint",
- "callback": "SamplePolicyInit",
- "args": {
- "arg1": "first_arg",
- "nextarg": "second arg value"
- }
- }, {
- "label": "onload-sample-api",
- "info": "Assert AlsaCore Presence",
- "api": "alsacore",
- "verb": "ping",
- "args": {"data": "none"}
- }, {
- "label": "onload-hal-lua",
- "info": "Load avaliable HALs",
- "lua": "_Alsa_Get_Hal"
- }
- ]
- }],
- "controls":
- [
- {
- "label": "multimedia",
- "actions": {
- "label": "multimedia-control-lua",
- "info": "Call Lua Script function Test_Lua_Engin",
- "lua": "_Audio_Set_Multimedia"
- }
- }, {
- "label": "navigation",
- "actions": {
- "label": "navigation-control-lua",
- "info": "Call Lua Script to set Navigation",
- "lua": "_Audio_Set_Navigation"
- }
- }, {
- "label": "emergency",
- "actions": {
- "label": "emergency-control-ucm",
- "lua": "_Audio_Set_Emergency"
- }
- }, {
- "label": "multi-step-sample",
- "info" : "all actions must succeed for control to be accepted",
- "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": {
- "test": "navigation"
- }
- }, {
- "label": "navigation-control-lua",
- "info": "Call Lua Script to set Navigation",
- "lua": "_Audio_Set_Navigation"
- }]
- }
- ],
- "events":
- [
- {
- "label": "SampleEvent1",
- "info": "define action when receiving a given event",
- "actions": [
- {
- "label": "Event Callback-1",
- "callback": "SampleControlEvent",
- "args": {
- "arg": "action-1"
- }
- }, {
- "label": "Event Callback-2",
- "callback": "SampleControlEvent",
- "args": {
- "arg": "action-2"
- }
- }
- ]
- },
- {
- "label": "SampleEvent2",
- "info": "define action when receiving a given event",
- "actions": [
- {
- "label": "Event Callback-1",
- "callback": "SampleControlEvent",
- "args": {
- "arg": "action-1"
- }
- }, {
- "label": "Event Callback-2",
- "callback": "SampleControlEvent",
- "args": {
- "arg": "action-2"
- }
- }
- ]
- }
- ]
-}
-
diff --git a/conf.d/project/json.d/onload-daemon-standalone.json b/conf.d/project/json.d/onload-daemon-standalone.json
deleted file mode 100644
index de52c22..0000000
--- a/conf.d/project/json.d/onload-daemon-standalone.json
+++ /dev/null
@@ -1,72 +0,0 @@
-{
- "$schema": "ToBeDone",
- "metadata": {
- "label": "sample-standalone-control",
- "info": "Minimal Standalone Controller Config",
- "version": "1.0"
- },
- "onload": [{
- "label": "onload-default",
- "info": "onload initialisation config",
- "actions":
- {
- "label": "control-init",
- "lua": "_Control_Init"
- }
- }],
- "controls":
- [
- {
- "label": "Button-1",
- "actions": {
- "label": "Action on Button One",
- "lua": "_Button_Press",
- "args": {
- "button": 1
- }
- }
- }, {
- "label": "Button-1",
- "actions": {
- "label": "Action on Button Two",
- "lua": "_Button_Press",
- "args": {
- "button": 2
- }
- }
- }, {
- "label": "Button-1",
- "actions": {
- "label": "Action on Button Three",
- "lua": "_Button_Press",
- "args": {
- "button": 3
- }
- }
- }
- ],
- "events":
- [
- {
- "label": "Event1",
- "actions": {
- "label": "Action Event 1",
- "lua": "_Event_Received",
- "args": {
- "evtname": "xxx"
- }
- }
- },
- {
- "label": "Event2",
- "actions": {
- "label": "Action Event 2",
- "lua": "_Event_Received",
- "args": {
- "evtname": "yyy"
- }
- }
- }
- ]
-}
-
diff --git a/conf.d/project/lua.d/CMakeLists.txt b/conf.d/project/lua.d/CMakeLists.txt
deleted file mode 100644
index 5cd61f2..0000000
--- a/conf.d/project/lua.d/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-###########################################################################
-# Copyright 2017 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.
-###########################################################################
-
-
-##################################################
-# Control Policy Config file
-##################################################
-PROJECT_TARGET_ADD(ctl-lua.d)
-
- file(GLOB LUA_FILES "*.lua")
-
- add_input_files("${LUA_FILES}")
-
- SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
- LABELS "DATA"
- OUTPUT_NAME ${TARGET_NAME}
- )
diff --git a/conf.d/project/lua.d/debug-helloworld.lua b/conf.d/project/lua.d/debug-helloworld.lua
deleted file mode 100644
index 7a41971..0000000
--- a/conf.d/project/lua.d/debug-helloworld.lua
+++ /dev/null
@@ -1,36 +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.
-
-
- Simple API script to be use with AGL control LuaDoCall API
- - After the script is loaded by lua_docall
- - Controller start function=xxxx where xxxx is taken from script filename doscript-xxxx-anything
-
---]]
-
-function _helloworld (request, query)
-
- AFB:notice ("LUA HelloWorld: Simple test query=%s", query);
-
- if (query == nil) then
- AFB:notice ("LUA HelloWorld:FX query should not be empty");
- AFB:fail (request, "LUA HelloWorld: query should not be empty");
- else
- AFB:notice ("LUA HelloWorld:OK query=%s", query);
- AFB:success (request, {arg0="Demat", arg1="Bonjours", arg2="Gootentag", arg3="Morning"});
- end
-
-end \ No newline at end of file
diff --git a/conf.d/project/lua.d/onload-aaaa-00-utils.lua b/conf.d/project/lua.d/onload-aaaa-00-utils.lua
deleted file mode 100644
index b8ecd7e..0000000
--- a/conf.d/project/lua.d/onload-aaaa-00-utils.lua
+++ /dev/null
@@ -1,86 +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.
-
- Note: this file should be called before any other to assert declare function
- is loaded before anything else.
-
- References:
- http://lua-users.org/wiki/DetectingUndefinedVariables
-
---]]
-
-
---===================================================
---= Niklas Frykholm
--- basically if user tries to create global variable
--- the system will not let them!!
--- call GLOBAL_lock(_G)
---
---===================================================
-function GLOBAL_lock(t)
- local mt = getmetatable(t) or {}
- mt.__newindex = lock_new_index
- setmetatable(t, mt)
-end
-
---===================================================
--- call GLOBAL_unlock(_G)
--- to change things back to normal.
---===================================================
-function GLOBAL_unlock(t)
- local mt = getmetatable(t) or {}
- mt.__newindex = unlock_new_index
- setmetatable(t, mt)
-end
-
-function lock_new_index(t, k, v)
- if (string.sub(k,1,1) ~= "_") then
- GLOBAL_unlock(_G)
- error("GLOBALS are locked -- " .. k ..
- " must be declared local or prefix with '_' for globals.", 2)
- else
- rawset(t, k, v)
- end
-end
-
-function unlock_new_index(t, k, v)
- rawset(t, k, v)
-end
-
--- return serialised version of printable table
-function Dump_Table(o)
- if type(o) == 'table' then
- local s = '{ '
- for k,v in pairs(o) do
- if type(k) ~= 'number' then k = '"'..k..'"' end
- s = s .. '['..k..'] = ' .. Dump_Table(v) .. ','
- end
- return s .. '} '
- else
- return tostring(o)
- end
-end
-
-
--- simulate C prinf function
-printf = function(s,...)
- io.write(s:format(...))
- io.write("\n")
- return
-end
-
--- lock global variable
-GLOBAL_lock(_G)
diff --git a/conf.d/project/lua.d/onload-aaaa-01-controls.lua b/conf.d/project/lua.d/onload-aaaa-01-controls.lua
deleted file mode 100644
index 24c4f71..0000000
--- a/conf.d/project/lua.d/onload-aaaa-01-controls.lua
+++ /dev/null
@@ -1,162 +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.
-
-
- Provide sample policy function for AGL Advance Audio Agent
---]]
-
--- Global HAL registry
-_Audio_Hal_Registry={}
-
--- Callback when receiving HAL registry
-function _Alsa_Get_Hal_CB (error, result, context)
- -- Initialise an empty table
- local registry={}
-
- -- Only process when response is valid
- if (error) then
- AFB_ErrOr ("[Audio_Init_CB] ErrOr result=%s", result)
- return
- end
-
- -- Extract response from result
- local response=result["response"]
-
- -- Index HAL Bindings APIs by shortname
- for key,value in pairs(response) do
- registry[value["shortname"]]=value["api"]
- end
-
- -- store Exiting HAL for further use
- printf ("-- [Audio_Init_CB] -- Audio_register_Hal=%s", Dump_Table(registry))
- _Audio_Hal_Registry=registry
-
-end
-
--- Function call at binding load time
-function _Alsa_Get_Hal(args)
-
- printf ("[-- Audio_Get_Hal --] args=%s", Dump_Table(argsT))
-
- -- Query AlsaCore for Active HALs (no query, no context)
- AFB:service ('alsacore', 'hallist', {}, "_Alsa_Get_Hal_CB", {})
-
-end
-
--- In sample configuration Query/Args parsing is common to all audio control
-local function Audio_Parse_Request (source, args, query)
-
- local apihal={}
-
- -- In this test we expect targeted device to be given from query (could come for args as well)
- if (query == nil ) then
- AFB:error ("--LUA:Audio_Set_Navigation query should contain and args with targeted apihal|device")
- return -- refuse control
- end
-
- -- Alsa Hook plugin asound sample config provides target sound card by name
- if (query["device"] ~= nil) then
- apihal=_Audio_Hal_Registry[query["device"]]
- end
-
- -- HTML5 test page provides directly HAL api.
- if (query["apihal"] ~= nil) then
- apihal= query["apihal"]
- end
-
- -- if requested HAL is not found then deny the control
- if (apihal == nil) then
- AFB:error ("--LUA:Audio_Set_Navigation No Active HAL Found")
- return -- refuse control
- end
-
- -- return api or nil when not found
- return apihal
-end
-
--- Set Navigation lower sound when play
-function _Audio_Set_Navigation(source, args, query)
-
- -- in strict mode every variables should be declared
- local err=0
- local ctlhal={}
- local response={}
- local apihal={}
-
- AFB:notice ("LUA:Audio_Set_Use_Case source=%d args=%s query=%s", source, args, query);
-
- -- Parse Query/Args and if HAL not found then refuse access
- apihal= Audio_Parse_Request (source, args, query)
- if (apihal == nil) then return 1 end
-
-
- -- if source < 0 then Alsa HookPlugin is closing PCM
- if (source < 0) then
- -- Ramp Up Multimedia channel synchronously
- ctlhal={['label']='Master_Playback_Volume', ['val']=100}
- err, response= AFB:servsync (apihal, 'ctlset',ctlhal)
- else
- -- Ramp Down Multimedia channel synchronously
- ctlhal={['label']='Master_Playback_Volume', ['val']=50}
- err, response= AFB:servsync (apihal, 'ctlset',ctlhal)
- end
-
- if (err) then
- AFB:error("--LUA:Audio_Set_Navigation halapi=%s refuse ctl=%s", apihal, ctlhal)
- return 1 -- control refused
- end
-
-
- return 0 -- control accepted
-end
-
-
--- Select Multimedia mode
-function _Audio_Set_Multimedia (source, args, query)
-
- -- in strict mode every variables should be declared
- local err=0
- local ctlhal={}
- local response={}
- local apihal={}
-
- AFB:notice ("LUA:Audio_Set_Use_Case source=%d args=%s query=%s", source, args, query);
-
- -- Parse Query/Args and if HAL not found then refuse access
- apihal= Audio_Parse_Request (source, args, query)
- if (apihal == nil) then return 1 end
-
-
- -- if Mumtimedia control only increase volume on open
- if (source >= 0) then
- -- Ramp Down Multimedia channel synchronously
- ctlhal={['label']='Master_Playback_Volume', ['val']=100}
- err, response= AFB:servsync (apihal, 'ctlset',ctlhal)
- end
-
- if (err) then
- AFB:error("--LUA:Audio_Set_Navigation halapi=%s refuse ctl=%s", apihal, ctlhal)
- return 1 -- control refused
- end
-
-
- return 0 -- control accepted
-end
-
--- Select Emergency Mode
-function _Audio_Set_Emergency(source, args, query)
- return 1 -- Always refuse in this test
-end
diff --git a/conf.d/project/lua.d/onload-aaaa-02-timer.lua b/conf.d/project/lua.d/onload-aaaa-02-timer.lua
deleted file mode 100644
index db7a937..0000000
--- a/conf.d/project/lua.d/onload-aaaa-02-timer.lua
+++ /dev/null
@@ -1,69 +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.
-
-
- Provide Sample Timer Handing to push event from LUA
---]]
-
--- Create event on Lua script load
-local MyEventHandle=AFB:evtmake("MyTestEvent")
-
--- Call count time every delay/ms
-local function Timer_Test_CB (timer, context)
-
- local evtinfo= AFB:timerget(timer)
- print ("timer=", Dump_Table(evtinfo))
-
- --send an event an event with count as value
- AFB:evtpush (MyEventHandle, {["label"]= evtinfo["label"], ["count"]=evtinfo["count"], ["info"]=context["info"]})
-
- -- note when timerCB return!=0 timer is kill
- return 0
-
-end
-
--- sendback event depending on count and delay
-function _Simple_Timer_Test (request, args)
-
- local context = {
- ["info"]="My 1st private Event",
- }
-
- -- if delay not defined default is 5s
- if (args["delay"]==nil) then args["delay"]=5000 end
-
- -- if count is not defined default is 10
- if (args["count"]==nil) then args["count"]=10 end
-
- -- we could use directly args but it is a sample
- local myTimer = {
- ["label"]=args["label"],
- ["delay"]=args["delay"],
- ["count"]=args["count"],
- }
- AFB:notice ("Test_Timer myTimer=%s", myTimer)
-
- -- subscribe to event
- AFB:subscribe (request, MyEventHandle)
-
- -- settimer take a table with delay+count as input (count==0 means infinite)
- AFB:timerset (myTimer, "Timer_Test_CB", context)
-
- -- nothing special to return send back args
- AFB:success (request, myTimer)
-
- return 0
-end
diff --git a/conf.d/project/lua.d/onload-aaaa-03-oncall.lua b/conf.d/project/lua.d/onload-aaaa-03-oncall.lua
deleted file mode 100644
index f9ccb67..0000000
--- a/conf.d/project/lua.d/onload-aaaa-03-oncall.lua
+++ /dev/null
@@ -1,70 +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.
-
-
- Provide sample LUA routines to be used with AGL control "lua_docall" API
---]]
-
---global counter to keep track of calls
-_count=0
-
--- Display receive arguments and echo them to caller
-function _Simple_Echo_Args (request, args)
- _count=_count+1
- AFB:notice("LUA OnCall Echo Args count=%d args=%s", count, args)
-
- print ("--inlua-- args=", Dump_Table(args))
-
- local response={
- ["count"]=_count,
- ["args"]=args,
- }
-
- -- fulup Embdeded table ToeDone AFB:success (request, response)
- AFB:success (request, {["func"]="Simple_Echo_Args", ["ret1"]=5678, ["ret2"]="abcd"})
-end
-
-local function Test_Async_CB (request, result, context)
- response={
- ["result"]=result,
- ["context"]=context,
- }
-
- AFB:notice ("Test_Async_CB result=%s context=%s", result, context)
- AFB:success (request, response)
-end
-
-function _Test_Call_Async (request, args)
- local context={
- ["value1"]="abcd",
- ["value2"]=1234
- }
-
- AFB:notice ("Test_Call_Async args=%s cb=Test_Async_CB", args)
- AFB:service("alsacore","ping", "Test_Async_CB", context)
-end
-
-function _Test_Call_Sync (request, args)
-
- AFB:notice ("Test_Call_Sync args=%s", args)
- local err, response= AFB:servsync ("alsacore","ping", args)
- if (err) then
- AFB:fail ("AFB:service_call_sync fail");
- else
- AFB:success (request, response)
- end
-end
-
diff --git a/conf.d/project/lua.d/standalone-sample/onload-daemon-00.lua b/conf.d/project/lua.d/standalone-sample/onload-daemon-00.lua
deleted file mode 100644
index b8ecd7e..0000000
--- a/conf.d/project/lua.d/standalone-sample/onload-daemon-00.lua
+++ /dev/null
@@ -1,86 +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.
-
- Note: this file should be called before any other to assert declare function
- is loaded before anything else.
-
- References:
- http://lua-users.org/wiki/DetectingUndefinedVariables
-
---]]
-
-
---===================================================
---= Niklas Frykholm
--- basically if user tries to create global variable
--- the system will not let them!!
--- call GLOBAL_lock(_G)
---
---===================================================
-function GLOBAL_lock(t)
- local mt = getmetatable(t) or {}
- mt.__newindex = lock_new_index
- setmetatable(t, mt)
-end
-
---===================================================
--- call GLOBAL_unlock(_G)
--- to change things back to normal.
---===================================================
-function GLOBAL_unlock(t)
- local mt = getmetatable(t) or {}
- mt.__newindex = unlock_new_index
- setmetatable(t, mt)
-end
-
-function lock_new_index(t, k, v)
- if (string.sub(k,1,1) ~= "_") then
- GLOBAL_unlock(_G)
- error("GLOBALS are locked -- " .. k ..
- " must be declared local or prefix with '_' for globals.", 2)
- else
- rawset(t, k, v)
- end
-end
-
-function unlock_new_index(t, k, v)
- rawset(t, k, v)
-end
-
--- return serialised version of printable table
-function Dump_Table(o)
- if type(o) == 'table' then
- local s = '{ '
- for k,v in pairs(o) do
- if type(k) ~= 'number' then k = '"'..k..'"' end
- s = s .. '['..k..'] = ' .. Dump_Table(v) .. ','
- end
- return s .. '} '
- else
- return tostring(o)
- end
-end
-
-
--- simulate C prinf function
-printf = function(s,...)
- io.write(s:format(...))
- io.write("\n")
- return
-end
-
--- lock global variable
-GLOBAL_lock(_G)
diff --git a/conf.d/project/lua.d/standalone-sample/onload-daemon-01.lua b/conf.d/project/lua.d/standalone-sample/onload-daemon-01.lua
deleted file mode 100644
index 7b22db0..0000000
--- a/conf.d/project/lua.d/standalone-sample/onload-daemon-01.lua
+++ /dev/null
@@ -1,57 +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.
-
- Note: this file should be called before any other to assert declare function
- is loaded before anything else.
-
- References:
- http://lua-users.org/wiki/DetectingUndefinedVariables
-
---]]
-
--- Set Navigation lower sound when play
-function _Control_Init(source, args)
-
- -- in strict mode every variables should be declared
- local err=0
-
- AFB:notice ("Control_Init args=%s", args);
-
- return 0 -- control accepted
-end
-
--- Set Navigation lower sound when play
-function _Button_Press(source, args, query)
-
- -- in strict mode every variables should be declared
- local err=0
-
- AFB:notice ("Button_Press button=%s", args["button"]);
-
- return 0 -- control accepted
-end
-
--- Set Navigation lower sound when play
-function _Event_Received(source, args, query)
-
- -- in strict mode every variables should be declared
- local err=0
-
- AFB:notice ("Event_Received event=%s", args["evtname"]);
-
- return 0 -- control accepted
-end
-