diff options
author | Fulup Ar Foll <fulup@iot.bzh> | 2017-08-23 01:00:20 +0200 |
---|---|---|
committer | Fulup Ar Foll <fulup@iot.bzh> | 2017-08-23 01:00:20 +0200 |
commit | c74ba24e19a5db52d237628aff012f9fb372f580 (patch) | |
tree | c60d2919e1c6941e95931231bf5f75720f9c959d | |
parent | c254a5b100b9ea011dc35b4079ce184e5c842135 (diff) |
Restore Basic HTML5 testing Scenario as a Standalone Controller
-rw-r--r-- | Controller-afb/filescan-utils.c | 128 | ||||
-rw-r--r-- | Controller-afb/filescan-utils.h | 41 | ||||
-rw-r--r-- | Controller-afb/wrap-json.c | 939 | ||||
-rw-r--r-- | Controller-afb/wrap-json.h | 46 | ||||
-rw-r--r-- | Controller-afb/wrap-json.md | 305 | ||||
-rw-r--r-- | afb-source/CMakeLists.txt (renamed from Controller-afb/CMakeLists.txt) | 1 | ||||
-rw-r--r-- | afb-source/ctl-apidef.h (renamed from Controller-afb/ctl-apidef.h) | 0 | ||||
-rw-r--r-- | afb-source/ctl-apidef.json (renamed from Controller-afb/ctl-apidef.json) | 0 | ||||
-rw-r--r-- | afb-source/ctl-binding.c (renamed from Controller-afb/ctl-binding.c) | 0 | ||||
-rw-r--r-- | afb-source/ctl-binding.h (renamed from Controller-afb/ctl-binding.h) | 0 | ||||
-rw-r--r-- | afb-source/ctl-dispatch.c (renamed from Controller-afb/ctl-dispatch.c) | 17 | ||||
-rw-r--r-- | afb-source/ctl-lua.c (renamed from Controller-afb/ctl-lua.c) | 0 | ||||
-rw-r--r-- | afb-source/ctl-plugin-sample.c (renamed from Controller-afb/ctl-plugin-sample.c) | 0 | ||||
-rw-r--r-- | afb-source/ctl-policy.c (renamed from Controller-afb/ctl-policy.c) | 0 | ||||
-rw-r--r-- | afb-source/ctl-timer.c (renamed from Controller-afb/ctl-timer.c) | 0 | ||||
-rw-r--r-- | conf.d/cmake/config.cmake | 3 | ||||
-rw-r--r-- | conf.d/project/.vscode/c_cpp_properties.json | 18 | ||||
-rw-r--r-- | conf.d/project/json.d/README.md | 20 | ||||
-rw-r--r-- | conf.d/project/json.d/onload-audio-control.json | 128 | ||||
-rw-r--r-- | conf.d/project/json.d/onload-daemon-sample.json (renamed from conf.d/project/json.d/onload-daemon-standalone.json) | 33 | ||||
-rw-r--r-- | conf.d/project/lua.d/onload-aaaa-01-controls.lua | 162 | ||||
-rw-r--r-- | conf.d/project/lua.d/onload-daemon-00-utils.lua (renamed from conf.d/project/lua.d/onload-aaaa-00-utils.lua) | 0 | ||||
-rw-r--r-- | conf.d/project/lua.d/onload-daemon-01-init.lua | 48 | ||||
-rw-r--r-- | conf.d/project/lua.d/onload-daemon-03-controls.lua | 47 | ||||
-rw-r--r-- | conf.d/project/lua.d/onload-daemon-04-oncall.lua (renamed from conf.d/project/lua.d/onload-aaaa-03-oncall.lua) | 0 | ||||
-rw-r--r-- | conf.d/project/lua.d/onload-daemon-10-event.lua (renamed from conf.d/project/lua.d/onload-aaaa-02-timer.lua) | 35 | ||||
-rw-r--r-- | conf.d/project/lua.d/standalone-sample/onload-daemon-00.lua | 86 | ||||
-rw-r--r-- | conf.d/project/lua.d/standalone-sample/onload-daemon-01.lua | 60 | ||||
-rw-r--r-- | htdocs/README.md | 2 | ||||
-rw-r--r-- | htdocs/audio-control.html | 45 | ||||
-rw-r--r-- | htdocs/audio-logic.html | 9 | ||||
-rw-r--r-- | htdocs/index.html | 38 | ||||
-rw-r--r-- | nbproject/configurations.xml | 198 | ||||
-rw-r--r-- | nbproject/project.xml | 26 |
34 files changed, 443 insertions, 1992 deletions
diff --git a/Controller-afb/filescan-utils.c b/Controller-afb/filescan-utils.c deleted file mode 100644 index dc5d786..0000000 --- a/Controller-afb/filescan-utils.c +++ /dev/null @@ -1,128 +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 <json-c/json.h> - -#include "ctl-binding.h" - -#ifndef PUBLIC - #define PUBLIC -#endif -#define STATIC static - -// 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; -} diff --git a/Controller-afb/filescan-utils.h b/Controller-afb/filescan-utils.h deleted file mode 100644 index cbe15de..0000000 --- a/Controller-afb/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/Controller-afb/wrap-json.c b/Controller-afb/wrap-json.c deleted file mode 100644 index 164e127..0000000 --- a/Controller-afb/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/Controller-afb/wrap-json.h b/Controller-afb/wrap-json.h deleted file mode 100644 index cb2d0bf..0000000 --- a/Controller-afb/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/Controller-afb/wrap-json.md b/Controller-afb/wrap-json.md deleted file mode 100644 index 92940f1..0000000 --- a/Controller-afb/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 -<apiref-pack>, 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/afb-source/CMakeLists.txt index 514c091..4c1ea66 100644 --- a/Controller-afb/CMakeLists.txt +++ b/afb-source/CMakeLists.txt @@ -63,6 +63,7 @@ PROJECT_TARGET_ADD(audio-plugin-sample) # Library dependencies (include updates automatically) TARGET_LINK_LIBRARIES(${TARGET_NAME} + afb-utilities ${link_libraries} ) diff --git a/Controller-afb/ctl-apidef.h b/afb-source/ctl-apidef.h index 9ce9e05..9ce9e05 100644 --- a/Controller-afb/ctl-apidef.h +++ b/afb-source/ctl-apidef.h diff --git a/Controller-afb/ctl-apidef.json b/afb-source/ctl-apidef.json index e2207d0..e2207d0 100644 --- a/Controller-afb/ctl-apidef.json +++ b/afb-source/ctl-apidef.json diff --git a/Controller-afb/ctl-binding.c b/afb-source/ctl-binding.c index 4f6ecd3..4f6ecd3 100644 --- a/Controller-afb/ctl-binding.c +++ b/afb-source/ctl-binding.c diff --git a/Controller-afb/ctl-binding.h b/afb-source/ctl-binding.h index 0d16e56..0d16e56 100644 --- a/Controller-afb/ctl-binding.h +++ b/afb-source/ctl-binding.h diff --git a/Controller-afb/ctl-dispatch.c b/afb-source/ctl-dispatch.c index 0104229..95d1315 100644 --- a/Controller-afb/ctl-dispatch.c +++ b/afb-source/ctl-dispatch.c @@ -22,6 +22,7 @@ #include <stdio.h> #include <string.h> #include <dlfcn.h> +#include <sys/prctl.h> #include "ctl-binding.h" @@ -356,7 +357,7 @@ STATIC DispatchHandleT *DispatchLoadOnload(DispatchConfigT *controlConfig, json_ int err; DispatchHandleT *dispatchHandle = calloc(1, sizeof (DispatchHandleT)); - err = wrap_json_unpack(onloadJ, "{ss,s?s, s?o,s?o,s?o !}", + 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)); @@ -525,19 +526,29 @@ STATIC DispatchConfigT *DispatchLoadConfig(const char* filepath) { 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); + err = wrap_json_unpack(controlConfigJ, "{s?s,s?o,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); + const char*ctlname=NULL; + err = wrap_json_unpack(metadataJ, "{ss,s?s,s?s,ss !}", "label", &controlConfig->label, "version", &controlConfig->version, "name", &ctlname, "info", &controlConfig->info); if (err) { AFB_ERROR("DISPATCH-LOAD-CONFIG:METADATA Missing something label|version|[label] in %s", json_object_get_string(metadataJ)); goto OnErrorExit; } + + // if ctlname is provided change process name now + if (ctlname) { + err= prctl(PR_SET_NAME, ctlname,NULL,NULL,NULL); + if (err) AFB_WARNING("Fail to set Process Name to:%s",ctlname); + } + } if (onloadsJ) { diff --git a/Controller-afb/ctl-lua.c b/afb-source/ctl-lua.c index 8d5a87e..8d5a87e 100644 --- a/Controller-afb/ctl-lua.c +++ b/afb-source/ctl-lua.c diff --git a/Controller-afb/ctl-plugin-sample.c b/afb-source/ctl-plugin-sample.c index 1d66802..1d66802 100644 --- a/Controller-afb/ctl-plugin-sample.c +++ b/afb-source/ctl-plugin-sample.c diff --git a/Controller-afb/ctl-policy.c b/afb-source/ctl-policy.c index e9798b3..e9798b3 100644 --- a/Controller-afb/ctl-policy.c +++ b/afb-source/ctl-policy.c diff --git a/Controller-afb/ctl-timer.c b/afb-source/ctl-timer.c index a826f9f..a826f9f 100644 --- a/Controller-afb/ctl-timer.c +++ b/afb-source/ctl-timer.c diff --git a/conf.d/cmake/config.cmake b/conf.d/cmake/config.cmake index cf2ff94..fec5082 100644 --- a/conf.d/cmake/config.cmake +++ b/conf.d/cmake/config.cmake @@ -47,6 +47,7 @@ set(PROJECT_APP_TEMPLATES_DIR "conf.d/app-templates") # ---------------------------------- set(CMAKE_BUILD_TYPE "DEBUG") + # Kernel selection if needed. You can choose between a # mandatory version to impose a minimal version. # Or check Kernel minimal version and just print a Warning @@ -133,7 +134,7 @@ set(COMPILE_OPTIONS # Print a helper message when every thing is finished # ---------------------------------------------------- -#set(CLOSING_MESSAGE "") +set(CLOSING_MESSAGE "Debug from ./buid: afb-daemon --port=1234 --ldpaths=. --workdir=. --roothttp=../htdocs --tracereq=common --token='' --verbose") set(PACKAGE_MESSAGE "Install widget file using in the target : afm-util install ${PROJECT_NAME}.wgt") # (BUG!!!) as PKG_CONFIG_PATH does not work [should be an env variable] diff --git a/conf.d/project/.vscode/c_cpp_properties.json b/conf.d/project/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..5512cb3 --- /dev/null +++ b/conf.d/project/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "null", + "includePath": [], + "defines": [], + "browse": { + "path": [ + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "intelliSenseMode": "clang-x64" + } + ], + "version": 2 +}
\ No newline at end of file diff --git a/conf.d/project/json.d/README.md b/conf.d/project/json.d/README.md new file mode 100644 index 0000000..153990c --- /dev/null +++ b/conf.d/project/json.d/README.md @@ -0,0 +1,20 @@ +By default controller searches for a config filename with the same 'middlename' as daemon process. As an example if your process name is afb-daemon then middle name is 'daemon'. + +``` + onload-middlename-xxxxx.json + + # Middlename is taken from process middlename. +``` + +You may overload config search path with environement variables + * AFB_BINDER_NAME: change patern config search path. 'export AFB_BINDER_NAME=sample' will make controller to search for a configfile name 'onload-sample-xxx.json'. + * CONTROL_CONFIG_PATH: change default reserch path for configuration. You may provide multiple directories separated by ':'. + * CONTROL_LUA_PATH: same as CONTROL_CONFIG_PATH but for Lua script files. + +Example to load a config name 'onload-myconfig-test.json' do +``` + AFB_BINDER_NAME='myconfig' afb-daemon --verbose ...' +``` + +Note: you may change search pattern for Lua script by adding 'ctlname=afb-middlename-xxx' in the metadata section of your config 'onload-*.json' + 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 2e6da77..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-sample.json index ab646fd..cb6ca55 100644 --- a/conf.d/project/json.d/onload-daemon-standalone.json +++ b/conf.d/project/json.d/onload-daemon-sample.json @@ -3,6 +3,7 @@ "metadata": { "label": "sample-standalone-control", "info": "Minimal Standalone Controller Config", + "name": "afb-sample-controller", "version": "1.0" }, "onload": [{ @@ -11,36 +12,32 @@ "actions": { "label": "control-init", - "lua": "_Control_Init" + "lua": "_Sample_Controller_Init", + "args": { + "xxxx": 1234, + "yyyy": "Bien le bonjours à vous", + "zzzz": "simple-evt" + } } }], "controls": [ { - "label": "Button-1", - "actions": { - "label": "Action on Button One", - "lua": "_Button_Press", - "args": { - "button": 1 - } - } - }, { - "label": "Button-1", + "label": "Button-Happy", "actions": { - "label": "Action on Button Two", - "lua": "_Button_Press", + "label": "Action Happy", + "lua": "_Button_Happy", "args": { - "button": 2 + "button": 5678 } } }, { - "label": "Button-1", + "label": "Button-UnHappy", "actions": { - "label": "Action on Button Three", - "lua": "_Button_Press", + "label": "Action Unhappy", + "lua": "_Button_UnHappy", "args": { - "button": 3 + "button": "abcd" } } } 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 6ffc8d3..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-00-utils.lua b/conf.d/project/lua.d/onload-daemon-00-utils.lua index 29d2c70..29d2c70 100644 --- a/conf.d/project/lua.d/onload-aaaa-00-utils.lua +++ b/conf.d/project/lua.d/onload-daemon-00-utils.lua diff --git a/conf.d/project/lua.d/onload-daemon-01-init.lua b/conf.d/project/lua.d/onload-daemon-01-init.lua new file mode 100644 index 0000000..ebdc678 --- /dev/null +++ b/conf.d/project/lua.d/onload-daemon-01-init.lua @@ -0,0 +1,48 @@ +--[[ + 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. +--]] + +-- Global variable SHOULD start with _ +_Global_Context={} + +--[[ + This function is call during controller init phase as describe in onload-daemon-sample.json + It receives two argument 1st one is the source (here on load) second one is the arguments + as expose in config file. + + In this sample we create an event that take the name of args["zzzz"], the resulting handle + is save into _Global_Context for further use. + + Note: init functions are not call from a client and thus do not receive query + +--]] +function _Sample_Controller_Init(source, control) + + printf ("[-- Sample_Controller_Init --] source=%d control=%s", source, Dump_Table(control)) + + -- if no argument return now + if (control==nil or control["zzzz"]==nil) then + printf ("[-- Sample_Controller_Init --] no event name given") + return + end + + -- set a count to make more visible each call + _Global_Context["counter"]=0 + + -- just for fun create an event + _Global_Context["event"]=AFB:evtmake(control["zzzz"]) + +end diff --git a/conf.d/project/lua.d/onload-daemon-03-controls.lua b/conf.d/project/lua.d/onload-daemon-03-controls.lua new file mode 100644 index 0000000..f65c019 --- /dev/null +++ b/conf.d/project/lua.d/onload-daemon-03-controls.lua @@ -0,0 +1,47 @@ +--[[ + 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. + + Following function are called when a client activate a control with + controller api -> APi=control VERB=dispatch + arguments are + - source (0) when requesting the control (-1) when releasing + - control comme from config given with 'args' in onload-middlename-xxxxx.json + - client is the argument part of the query as providing by client requesting the control. + +--]] + + + +-- Simple Happy(granted) Control +function _Button_Happy(source, control, client) + + -- print argument to make sure we understant what we get + printf ("[-- _Button_Happy --] source=%d control=%s client=%s", source, Dump_Table(client), Dump_Table(control)) + + AFB:notice ("[-- _Button_Happy --] To Be Done") + return 0 -- control granted +end + + +-- Simple UnHappy(debu) Control +function _Button_UnHappy(source, control, client) + + -- print argument to make sure we understant what we get + printf ("[-- _Button_UnHappy --] source=%d control=%s client=%s", source, Dump_Table(client), Dump_Table(control)) + + AFB:error ("[-- _Button_UnHappy --] To Be Done") + return 1 -- control is refused +end diff --git a/conf.d/project/lua.d/onload-aaaa-03-oncall.lua b/conf.d/project/lua.d/onload-daemon-04-oncall.lua index 4e78fd8..4e78fd8 100644 --- a/conf.d/project/lua.d/onload-aaaa-03-oncall.lua +++ b/conf.d/project/lua.d/onload-daemon-04-oncall.lua diff --git a/conf.d/project/lua.d/onload-aaaa-02-timer.lua b/conf.d/project/lua.d/onload-daemon-10-event.lua index f984f3f..c0b21f9 100644 --- a/conf.d/project/lua.d/onload-aaaa-02-timer.lua +++ b/conf.d/project/lua.d/onload-daemon-10-event.lua @@ -19,16 +19,16 @@ --]] -- Create event on Lua script load -local MyEventHandle=AFB:evtmake("MyTestEvent") +_MyContext={} --- Call count time every delay/ms -local function Timer_Test_CB (timer, context) +-- WARNING: call back are global and should start with '_' +function _Timer_Test_CB (timer, context) local evtinfo= AFB:timerget(timer) - print ("timer=", Dump_Table(evtinfo)) + printf ("[-- _Timer_Test_C --] evtInfo=%s", Dump_Table(evtinfo)) --send an event an event with count as value - AFB:evtpush (MyEventHandle, {["label"]= evtinfo["label"], ["count"]=evtinfo["count"], ["info"]=context["info"]}) + AFB:evtpush (_MyContext["event"], {["label"]= evtinfo["label"], ["count"]=evtinfo["count"], ["info"]=context["info"]}) -- note when timerCB return!=0 timer is kill return 0 @@ -36,33 +36,38 @@ local function Timer_Test_CB (timer, context) end -- sendback event depending on count and delay -function _Simple_Timer_Test (request, args) +function _Simple_Timer_Test (request, client) local context = { ["info"]="My 1st private Event", } + -- if event does not exit create it now. + if (_MyContext["event"] == nil) then + _MyContext["event"]= AFB:evtmake(client["label"]) + end + -- if delay not defined default is 5s - if (args["delay"]==nil) then args["delay"]=5000 end + if (client["delay"]==nil) then client["delay"]=5000 end -- if count is not defined default is 10 - if (args["count"]==nil) then args["count"]=10 end + if (client["count"]==nil) then client["count"]=10 end - -- we could use directly args but it is a sample + -- we could use directly client but it is a sample local myTimer = { - ["label"]=args["label"], - ["delay"]=args["delay"], - ["count"]=args["count"], + ["label"]=client["label"], + ["delay"]=client["delay"], + ["count"]=client["count"], } AFB:notice ("Test_Timer myTimer=%s", myTimer) -- subscribe to event - AFB:subscribe (request, MyEventHandle) + AFB:subscribe (request, _MyContext["event"]) -- settimer take a table with delay+count as input (count==0 means infinite) - AFB:timerset (myTimer, "Timer_Test_CB", context) + AFB:timerset (myTimer, "_Timer_Test_CB", context) - -- nothing special to return send back args + -- nothing special to return send back AFB:success (request, myTimer) return 0 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 29d2c70..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 b423914..0000000 --- a/conf.d/project/lua.d/standalone-sample/onload-daemon-01.lua +++ /dev/null @@ -1,60 +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); - AFB:success(source, 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"]); - AFB:success(source, args) - - 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"]); - AFB:success(source, args) - - return 0 -- control accepted -end - diff --git a/htdocs/README.md b/htdocs/README.md index bb14b7e..0ad2260 100644 --- a/htdocs/README.md +++ b/htdocs/README.md @@ -3,5 +3,5 @@ ------------------------------------------------------------------------ # Load bindings directly from development tree for debug - afb-daemon --verbose --verbose --token="" --ldpaths=build --port=1234 --roothttp=htdocs + AFB_BINDER_NAME='sample' afb-daemon --verbose --verbose --token="" --ldpaths=build --port=1234 --roothttp=htdocs diff --git a/htdocs/audio-control.html b/htdocs/audio-control.html deleted file mode 100644 index 06010e5..0000000 --- a/htdocs/audio-control.html +++ /dev/null @@ -1,45 +0,0 @@ -<html> -<head> - <title>Basic Audio Hardware Abstraction Layer Test</title> - <link rel="stylesheet" href="AudioBinding.css"> - <script type="text/javascript" src="AFB-websock.js"></script> - <script type="text/javascript" src="AudioBinding.js"></script> -</head> - -<body onload="init('hal_registry','alsacore', 'hallist')"> - - <h1>Simple Audio Control Test</h1> - <button id="connected" onclick="init('hal_registry','alsacore', 'hallist')">Binder WS Fail</button> - <br><br> - <b>Selected HAL </b> - <select id='hal_registry'></select> - - <b>API Verbosity </b> - <select id='api_verbosity' onclick='mode=this.value'> - <option value='0'>Quiet</option> - <option value='1'>Compact</option> - <option value='2'>Verbose</option> - <option value='3'>Full</option> - </select> - <br> - <br> - - <ol> - - <li><button onclick="callbinder('control','dispatch' ,{'target':'navigation','args':{'apihal':sndcard}});">Dispatch Navigation</button></li> - <li><button onclick="callbinder('control','dispatch' ,{'target':'multimedia','args':{'apihal':sndcard}});">Dispatch Mutimedia</button></li> - <li><button onclick="callbinder('control','dispatch' ,{'target':'emergency' });">Dispatch Emergency</button></li> - <br> - <li><button onclick="callbinder('control','request' , {'target':'_Simple_Echo_Args', 'args':{speed:20}});">LUA function</button></li> - <li><button onclick="callbinder('control','request' , {'target':'_Simple_Timer_Test', args:{label:'MyTimer', 'delay':3000, 'count':10}});">LUA Timer</button></li> - <li><button onclick="callbinder('control','debuglua' , {'target':'helloworld', args:{'arg1':'abcd', 'next':7890, 'last':[1,2,3,4]}});">LUA script</button></li> - - </ol> - - <div id="main" style="visibility:hidden"> - <ol> - <li>Question <pre id="question"></pre> - <li>Response <pre id="output"></pre> - <li>Events: <pre id="outevt"></pre> - </ol> - </div> diff --git a/htdocs/audio-logic.html b/htdocs/audio-logic.html deleted file mode 100644 index c31282a..0000000 --- a/htdocs/audio-logic.html +++ /dev/null @@ -1,9 +0,0 @@ -<html> -<head> - <title>High Level API Simple Test Page</title> - - <script type="text/javascript" src="AFB-websock.js"></script> - <script type="text/javascript" src="AudioBinding.js"></script> -</head> - -ToBeDone
\ No newline at end of file diff --git a/htdocs/index.html b/htdocs/index.html index 828d389..19d5315 100644 --- a/htdocs/index.html +++ b/htdocs/index.html @@ -1,7 +1,35 @@ <html> - <head> - <title>AGL-AudioBindins tests</title> - <body> - <h1>Controller for AAAA test</h1> +<head> + <title>Simple COntroller Test</title> + <link rel="stylesheet" href="AudioBinding.css"> + <script type="text/javascript" src="AFB-websock.js"></script> + <script type="text/javascript" src="AudioBinding.js"></script> +</head> + +<body onload="init('hal_registry','alsacore', 'hallist')"> + + <h1>Simple Control Test</h1> + <button id="connected" onclick="init('hal_registry','alsacore', 'hallist')">Binder WS Fail</button> + <br><br> + + <ol> - <li><a href="audio-control.html">AudioControl Control/Policy API</a> + + <li><button onclick="callbinder('control','dispatch' ,{'target':'Button-Happy',args:{'var1':1234, 'var2':4567}});">Button Happy (Granted)</button></li> + <li><button onclick="callbinder('control','dispatch' ,{'target':'Button-UnHappy',args:{'var1':1234, 'var2':4567}});">Button UnHappy (Refused)</button></li> + <br> + <li><button onclick="callbinder('control','request' ,{'target':'_Simple_Timer_Test',args:{'label':'myTimer', 'delay':3000, 'count':10}});">Start Events Timer</button></li> + <br> + <li><button onclick="callbinder('control','request' ,{'target':'_Simple_Echo_Args', 'args':{speed:20}});">Simple Echo args</button></li> + <br> + <li><button onclick="callbinder('control','debuglua' ,{'target':'helloworld', args:{'arg1':'abcd', 'next':7890, 'last':[1,2,3,4]}});">Lua Debug Script</button></li> + + </ol> + + <div id="main" style="visibility:hidden"> + <ol> + <li>Question <pre id="question"></pre> + <li>Response <pre id="output"></pre> + <li>Events: <pre id="outevt"></pre> + </ol> + </div> diff --git a/nbproject/configurations.xml b/nbproject/configurations.xml new file mode 100644 index 0000000..d427c2c --- /dev/null +++ b/nbproject/configurations.xml @@ -0,0 +1,198 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configurationDescriptor version="100"> + <logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT"> + <df root="." name="0"> + <df name="afb-source"> + <in>ctl-binding.c</in> + <in>ctl-dispatch.c</in> + <in>ctl-lua.c</in> + <in>ctl-plugin-sample.c</in> + <in>ctl-policy.c</in> + <in>ctl-timer.c</in> + <in>filescan-utils.c</in> + <in>wrap-json.c</in> + </df> + <df name="afb-utilities"> + <in>filescan-utils.c</in> + <in>wrap-json.c</in> + </df> + <df name="build"> + <df name="CMakeFiles"> + <df name="3.5.2"> + <df name="CompilerIdC"> + <in>CMakeCCompilerId.c</in> + </df> + <df name="CompilerIdCXX"> + <in>CMakeCXXCompilerId.cpp</in> + </df> + </df> + <in>feature_tests.c</in> + <in>feature_tests.cxx</in> + </df> + </df> + </df> + <logicalFolder name="ExternalFiles" + displayName="Important Files" + projectFiles="false" + kind="IMPORTANT_FILES_FOLDER"> + <itemPath>CMakeLists.txt</itemPath> + <itemPath>Makefile</itemPath> + <itemPath>nbproject/private/launcher.properties</itemPath> + </logicalFolder> + </logicalFolder> + <sourceFolderFilter>^(nbproject)$</sourceFolderFilter> + <sourceRootList> + <Elem>.</Elem> + </sourceRootList> + <projectmakefile>Makefile</projectmakefile> + <confs> + <conf name="Default" type="0"> + <toolsSet> + <compilerSet>default</compilerSet> + <dependencyChecking>false</dependencyChecking> + <rebuildPropChanged>false</rebuildPropChanged> + </toolsSet> + <flagsDictionary> + <element flagsID="0" commonFlags="-mtune=generic -march=x86-64 -g -fPIC"/> + </flagsDictionary> + <codeAssistance> + <includeAdditional>true</includeAdditional> + </codeAssistance> + <makefileType> + <makeTool> + <buildCommandWorkingDir>build</buildCommandWorkingDir> + <buildCommand>${MAKE} -f Makefile</buildCommand> + <cleanCommand>${MAKE} -f Makefile clean</cleanCommand> + <executablePath></executablePath> + <ccTool> + <incDir> + <pElem>.</pElem> + </incDir> + </ccTool> + </makeTool> + <preBuild> + <preBuildCommandWorkingDir>build</preBuildCommandWorkingDir> + <preBuildCommand>cmake ..</preBuildCommand> + <preBuildFirst>true</preBuildFirst> + </preBuild> + </makefileType> + <item path="afb-source/ctl-binding.c" ex="false" tool="0" flavor2="3"> + <cTool flags="0"> + <incDir> + <pElem>../../../opt/include/afb</pElem> + <pElem>afb-source</pElem> + <pElem>build/afb-source</pElem> + </incDir> + </cTool> + </item> + <item path="afb-source/ctl-dispatch.c" ex="false" tool="0" flavor2="3"> + <cTool flags="0"> + <incDir> + <pElem>../../../opt/include/afb</pElem> + <pElem>afb-source</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/lua5.3</pElem> + <pElem>afb-utilities</pElem> + <pElem>../../../opt/include</pElem> + <pElem>build/afb-source</pElem> + </incDir> + </cTool> + </item> + <item path="afb-source/ctl-lua.c" ex="false" tool="0" flavor2="3"> + <cTool flags="0"> + <incDir> + <pElem>../../../opt/include/afb</pElem> + <pElem>afb-source</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/lua5.3</pElem> + <pElem>afb-utilities</pElem> + <pElem>../../../opt/include</pElem> + <pElem>build/afb-source</pElem> + </incDir> + </cTool> + </item> + <item path="afb-source/ctl-plugin-sample.c" ex="false" tool="0" flavor2="3"> + <cTool flags="0"> + <incDir> + <pElem>../../../opt/include/afb</pElem> + <pElem>afb-source</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>/usr/include/lua5.3</pElem> + <pElem>build/afb-source</pElem> + </incDir> + </cTool> + </item> + <item path="afb-source/ctl-policy.c" ex="false" tool="0" flavor2="2"> + <cTool> + <incDir> + <pElem>.</pElem> + </incDir> + </cTool> + </item> + <item path="afb-source/ctl-timer.c" ex="false" tool="0" flavor2="3"> + <cTool flags="0"> + <incDir> + <pElem>../../../opt/include/afb</pElem> + <pElem>afb-source</pElem> + <pElem>../../../opt/include</pElem> + <pElem>build/afb-source</pElem> + </incDir> + </cTool> + </item> + <item path="afb-source/filescan-utils.c" ex="false" tool="0" flavor2="2"> + <cTool> + <incDir> + <pElem>.</pElem> + </incDir> + </cTool> + </item> + <item path="afb-source/wrap-json.c" ex="false" tool="0" flavor2="2"> + <cTool> + <incDir> + <pElem>.</pElem> + </incDir> + </cTool> + </item> + <item path="afb-utilities/filescan-utils.c" ex="false" tool="0" flavor2="3"> + <cTool flags="0"> + <incDir> + <pElem>../../../opt/include/afb</pElem> + <pElem>afb-utilities</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>build/afb-utilities</pElem> + </incDir> + </cTool> + </item> + <item path="afb-utilities/wrap-json.c" ex="false" tool="0" flavor2="3"> + <cTool flags="0"> + <incDir> + <pElem>afb-utilities</pElem> + <pElem>/usr/include/json-c</pElem> + <pElem>build/afb-utilities</pElem> + </incDir> + </cTool> + </item> + <item path="build/CMakeFiles/3.5.2/CompilerIdC/CMakeCCompilerId.c" + ex="false" + tool="0" + flavor2="2"> + </item> + <item path="build/CMakeFiles/3.5.2/CompilerIdCXX/CMakeCXXCompilerId.cpp" + ex="false" + tool="1" + flavor2="4"> + </item> + <item path="build/CMakeFiles/feature_tests.c" ex="false" tool="0" flavor2="2"> + </item> + <item path="build/CMakeFiles/feature_tests.cxx" ex="false" tool="1" flavor2="4"> + </item> + <folder path="0/build"> + <cTool> + <incDir> + <pElem>.</pElem> + </incDir> + </cTool> + </folder> + </conf> + </confs> +</configurationDescriptor> diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..193a3cd --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://www.netbeans.org/ns/project/1"> + <type>org.netbeans.modules.cnd.makeproject</type> + <configuration> + <data xmlns="http://www.netbeans.org/ns/make-project/1"> + <name>AFB-Controller</name> + <c-extensions>c</c-extensions> + <cpp-extensions>cpp,cxx</cpp-extensions> + <header-extensions>h</header-extensions> + <sourceEncoding>UTF-8</sourceEncoding> + <make-dep-projects/> + <sourceRootList> + <sourceRootElem>.</sourceRootElem> + </sourceRootList> + <confList> + <confElem> + <name>Default</name> + <type>0</type> + </confElem> + </confList> + <formatting> + <project-formatting-style>false</project-formatting-style> + </formatting> + </data> + </configuration> +</project> |