summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFulup Ar Foll <fulup@iot.bzh>2017-08-23 01:00:20 +0200
committerFulup Ar Foll <fulup@iot.bzh>2017-08-23 01:00:20 +0200
commitc74ba24e19a5db52d237628aff012f9fb372f580 (patch)
treec60d2919e1c6941e95931231bf5f75720f9c959d
parentc254a5b100b9ea011dc35b4079ce184e5c842135 (diff)
Restore Basic HTML5 testing Scenario as a Standalone Controller
-rw-r--r--Controller-afb/filescan-utils.c128
-rw-r--r--Controller-afb/filescan-utils.h41
-rw-r--r--Controller-afb/wrap-json.c939
-rw-r--r--Controller-afb/wrap-json.h46
-rw-r--r--Controller-afb/wrap-json.md305
-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.cmake3
-rw-r--r--conf.d/project/.vscode/c_cpp_properties.json18
-rw-r--r--conf.d/project/json.d/README.md20
-rw-r--r--conf.d/project/json.d/onload-audio-control.json128
-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.lua162
-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.lua48
-rw-r--r--conf.d/project/lua.d/onload-daemon-03-controls.lua47
-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.lua86
-rw-r--r--conf.d/project/lua.d/standalone-sample/onload-daemon-01.lua60
-rw-r--r--htdocs/README.md2
-rw-r--r--htdocs/audio-control.html45
-rw-r--r--htdocs/audio-logic.html9
-rw-r--r--htdocs/index.html38
-rw-r--r--nbproject/configurations.xml198
-rw-r--r--nbproject/project.xml26
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
-&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/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>