diff options
author | José Bollo <jose.bollo@iot.bzh> | 2018-04-09 18:16:07 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2018-06-15 17:57:36 +0200 |
commit | 4521c1e7ae5371ab9d639adc617d17fb4e8ded0c (patch) | |
tree | a8a1416a2d58c16ab3993c7e4dc405fc71daab6a /include | |
parent | 63682b4da9d3e892d1d0a671de860adc43068142 (diff) |
api-v3: First draft
This commit introduces the bindings v3 API for bindings.
The documentation has still to be improved and will come
very soon.
Change-Id: I8f9007370e29f671fdfd1da87fff7372a17db7af
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
Diffstat (limited to 'include')
40 files changed, 4441 insertions, 2157 deletions
diff --git a/include/afb/afb-api-x3-itf.h b/include/afb/afb-api-x3-itf.h new file mode 100644 index 00000000..38b29196 --- /dev/null +++ b/include/afb/afb-api-x3-itf.h @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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 + +/* declared here */ +struct afb_api_x3; +struct afb_api_x3_itf; + +/* referenced here */ +struct sd_event; +struct sd_bus; +struct afb_req_x2; +struct afb_event_x2; +struct afb_auth; +struct afb_verb_v2; +struct afb_verb_v3; + +/** + * Structure for the APIv3 + */ +struct afb_api_x3 +{ + /** + * Interface functions + * + * Don't use it directly, prefer helper functions. + */ + const struct afb_api_x3_itf *itf; + + /** + * The name of the api + * + * @see afb_api_x3_name + */ + const char *apiname; + + /** + * User defined data + * + * @see afb_api_x3_set_userdata + * @see afb_api_x3_get_userdata + */ + void *userdata; + + /** + * Current verbosity mask + * + * The bits tells what verbosity is required for the api. + * It is related to the syslog levels. + * + * EMERGENCY 0 System is unusable + * ALERT 1 Action must be taken immediately + * CRITICAL 2 Critical conditions + * ERROR 3 Error conditions + * WARNING 4 Warning conditions + * NOTICE 5 Normal but significant condition + * INFO 6 Informational + * DEBUG 7 Debug-level messages + */ + int logmask; +}; + +/** + * Definition of the function's interface for the APIv3 + */ +struct afb_api_x3_itf +{ + /* CAUTION: respect the order, add at the end */ + + /** sending log messages */ + void (*vverbose)( + struct afb_api_x3 *api, + int level, + const char *file, + int line, + const char * func, + const char *fmt, + va_list args); + + /** gets the common systemd's event loop */ + struct sd_event *(*get_event_loop)( + struct afb_api_x3 *api); + + /** gets the common systemd's user d-bus */ + struct sd_bus *(*get_user_bus)( + struct afb_api_x3 *api); + + /** gets the common systemd's system d-bus */ + struct sd_bus *(*get_system_bus)( + struct afb_api_x3 *api); + + /** get the file descriptor for the root directory */ + int (*rootdir_get_fd)( + struct afb_api_x3 *api); + + /** get a file using locale setting */ + int (*rootdir_open_locale)( + struct afb_api_x3 *api, + const char *filename, + int flags, + const char *locale); + + /** queue a job */ + int (*queue_job)( + struct afb_api_x3 *api, + void (*callback)(int signum, void *arg), + void *argument, + void *group, + int timeout); + + /** requires an api initialized or not */ + int (*require_api)( + struct afb_api_x3 *api, + const char *name, + int initialized); + + /** add an alias */ + int (*add_alias)( + struct afb_api_x3 *api, + const char *name, + const char *as_name); + + /** broadcasts event 'name' with 'object' */ + int (*event_broadcast)( + struct afb_api_x3 *api, + const char *name, + struct json_object *object); + + /** creates an event of 'name' */ + struct afb_event_x2 *(*event_make)( + struct afb_api_x3 *api, + const char *name); + + /** legacy asynchronous invocation */ + void (*legacy_call)( + struct afb_api_x3 *api, + const char *apiname, + const char *verb, + struct json_object *args, + void (*callback)(void*, int, struct json_object*, struct afb_api_x3 *), + void *closure); + + /** legacy synchronous invocation */ + int (*legacy_call_sync)( + struct afb_api_x3 *api, + const char *apiname, + const char *verb, + struct json_object *args, + struct json_object **result); + + /** creation of a new api*/ + struct afb_api_x3 *(*api_new_api)( + struct afb_api_x3 *api, + const char *apiname, + const char *info, + int noconcurrency, + int (*preinit)(void*, struct afb_api_x3 *), + void *closure); + + /** set verbs of the api using v2 description */ + int (*api_set_verbs_v2)( + struct afb_api_x3 *api, + const struct afb_verb_v2 *verbs); + + /** add one verb to the api */ + int (*api_add_verb)( + struct afb_api_x3 *api, + const char *verb, + const char *info, + void (*callback)(struct afb_req_x2 *req), + void *vcbdata, + const struct afb_auth *auth, + uint32_t session, + int glob); + + /** delete one verb of the api */ + int (*api_del_verb)( + struct afb_api_x3 *api, + const char *verb, + void **vcbdata); + + /** set the api's callback for processing events */ + int (*api_set_on_event)( + struct afb_api_x3 *api, + void (*onevent)(struct afb_api_x3 *api, const char *event, struct json_object *object)); + + /** set the api's callback for initialisation */ + int (*api_set_on_init)( + struct afb_api_x3 *api, + int (*oninit)(struct afb_api_x3 *api)); + + /** seal the api */ + void (*api_seal)( + struct afb_api_x3 *api); + + /** set verbs of the api using v3 description */ + int (*api_set_verbs_v3)( + struct afb_api_x3 *api, + const struct afb_verb_v3 *verbs); + + /** add an event handler for the api */ + int (*event_handler_add)( + struct afb_api_x3 *api, + const char *pattern, + void (*callback)(void *, const char*, struct json_object*, struct afb_api_x3*), + void *closure); + + /** delete an event handler of the api */ + int (*event_handler_del)( + struct afb_api_x3 *api, + const char *pattern, + void **closure); + + /** asynchronous call for the api */ + void (*call)( + struct afb_api_x3 *api, + const char *apiname, + const char *verb, + struct json_object *args, + void (*callback)(void*, struct json_object*, const char*, const char*, struct afb_api_x3 *), + void *closure); + + /** synchronous call for the api */ + int (*call_sync)( + struct afb_api_x3 *api, + const char *apiname, + const char *verb, + struct json_object *args, + struct json_object **result, + char **error, + char **info); + + /** indicate provided classes of the api */ + int (*class_provide)( + struct afb_api_x3 *api, + const char *name); + + /** indicate required classes of the api */ + int (*class_require)( + struct afb_api_x3 *api, + const char *name); + + /** delete the api */ + int (*delete_api)( + struct afb_api_x3 *api); +}; + diff --git a/include/afb/afb-api-x3.h b/include/afb/afb-api-x3.h new file mode 100644 index 00000000..81323ef5 --- /dev/null +++ b/include/afb/afb-api-x3.h @@ -0,0 +1,884 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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 "afb-verbosity.h" +#include "afb-api-x3-itf.h" + +/** + * Get the name of the 'api'. + * + * @param api the api whose name is to be returned + * + * @return the name of the api. + * + * The returned value must not be changed nor freed. + */ +static inline +const char *afb_api_x3_name(struct afb_api_x3 *api) +{ + return api->apiname; +} + +/** + * Get the "userdata" pointer of the 'api' + * + * @param api the api whose user's data is to be returned + * + * @return the user's data pointer of the api. + * + * @see afb_api_x3_set_userdata + */ +static inline +void *afb_api_x3_get_userdata(struct afb_api_x3 *api) +{ + return api->userdata; +} + +/** + * Set the "userdata" pointer of the 'api' to 'value' + * + * @param api the api whose user's data is to be set + * @param value the data to set + * + * @see afb_api_x3_get_userdata + */ +static inline +void afb_api_x3_set_userdata(struct afb_api_x3 *api, void *value) +{ + api->userdata = value; +} + +/** + * Is the log message of 'level (as defined for syslog) required for the api? + * + * @param api the api to check + * @param level the level to check as defined for syslog: + * + * EMERGENCY 0 System is unusable + * ALERT 1 Action must be taken immediately + * CRITICAL 2 Critical conditions + * ERROR 3 Error conditions + * WARNING 4 Warning conditions + * NOTICE 5 Normal but significant condition + * INFO 6 Informational + * DEBUG 7 Debug-level messages + * + * @return 0 if not required or a value not null if required + * + * @see syslog + */ +static inline +int afb_api_x3_wants_log_level(struct afb_api_x3 *api, int level) +{ + return AFB_SYSLOG_MASK_WANT(api->logmask, level); +} + +/** + * Send to the journal with the log 'level' a message described + * by 'fmt' applied to the va-list 'args'. + * + * 'file', 'line' and 'func' are indicators of position of the code in source files + * (see macros __FILE__, __LINE__ and __func__). + * + * 'level' is defined by syslog standard: + * + * EMERGENCY 0 System is unusable + * ALERT 1 Action must be taken immediately + * CRITICAL 2 Critical conditions + * ERROR 3 Error conditions + * WARNING 4 Warning conditions + * NOTICE 5 Normal but significant condition + * INFO 6 Informational + * DEBUG 7 Debug-level messages + * + * @param api the api that collects the logging message + * @param level the level of the message + * @param file the source file that logs the messages or NULL + * @param line the line in the source file that logs the message + * @param func the name of the function in the source file that logs + * @param fmt the format of the message as in printf + * @param args the arguments to the format string of the message as a va_list + * + * @see syslog + * @see printf + */ +static inline +void afb_api_x3_vverbose(struct afb_api_x3 *api, int level, const char *file, int line, const char *func, const char *fmt, va_list args) +{ + api->itf->vverbose(api, level, file, line, func, fmt, args); +} + +/** + * Send to the journal with the log 'level' a message described + * by 'fmt' and following parameters. + * + * 'file', 'line' and 'func' are indicators of position of the code in source files + * (see macros __FILE__, __LINE__ and __func__). + * + * 'level' is defined by syslog standard: + * EMERGENCY 0 System is unusable + * ALERT 1 Action must be taken immediately + * CRITICAL 2 Critical conditions + * ERROR 3 Error conditions + * WARNING 4 Warning conditions + * NOTICE 5 Normal but significant condition + * INFO 6 Informational + * DEBUG 7 Debug-level messages + * + * @param api the api that collects the logging message + * @param level the level of the message + * @param file the source file that logs the messages or NULL + * @param line the line in the source file that logs the message + * @param func the name of the function in the source file that logs + * @param fmt the format of the message as in printf + * @param ... the arguments to the format string of the message + * + * @see syslog + * @see printf + */ +__attribute__((format(printf, 6, 7))) +static inline +void afb_api_x3_verbose( + struct afb_api_x3 *api, + int level, + const char *file, + int line, + const char *func, + const char *fmt, + ...) +{ + va_list args; + va_start(args, fmt); + api->itf->vverbose(api, level, file, line, func, fmt, args); + va_end(args); +} + +/** + * Retrieves the common systemd's event loop of AFB + * + * @param api the api that uses the event loop + * + * @return the systemd event loop if active, NULL otherwise + * + * @see afb_api_x3_get_user_bus + * @see afb_api_x3_get_system_bus + */ +static inline +struct sd_event *afb_api_x3_get_event_loop(struct afb_api_x3 *api) +{ + return api->itf->get_event_loop(api); +} + +/** + * Retrieves the common systemd's user/session d-bus of AFB + * + * @param api the api that uses the user dbus + * + * @return the systemd user connection to dbus if active, NULL otherwise + * + * @see afb_api_x3_get_event_loop + * @see afb_api_x3_get_system_bus + */ +static inline +struct sd_bus *afb_api_x3_get_user_bus(struct afb_api_x3 *api) +{ + return api->itf->get_user_bus(api); +} + +/** + * Retrieves the common systemd's system d-bus of AFB + * + * @param api the api that uses the system dbus + * + * @return the systemd system connection to dbus if active, NULL otherwise + * + * @see afb_api_x3_get_event_loop + * @see afb_api_x3_get_user_bus + */ + +static inline +struct sd_bus *afb_api_x3_get_system_bus(struct afb_api_x3 *api) +{ + return api->itf->get_system_bus(api); +} + +/** + * Get the root directory file descriptor. This file descriptor can + * be used with functions 'openat', 'fstatat', ... + * + * CAUTION, manipulate this this descriptor with care, in particular, don't close + * it. + * + * This can be used to get the path of the root directory using: + * + * ```C + * char buffer[MAX_PATH]; + * int dirfd = afb_api_x3_rootdir_get_fd(api); + * snprintf(buffer, sizeof buffer, "/proc/self/fd/%d", dirfd); + * readlink(buffer, buffer, sizeof buffer); + * ``` + * + * But note that within AGL this is the value given by the environment variable + * AFM_APP_INSTALL_DIR. + * + * @param api the api that uses the directory file descriptor + * + * @return the file descriptor of the root directory. + * + * @see afb_api_x3_rootdir_open_locale + */ +static inline +int afb_api_x3_rootdir_get_fd(struct afb_api_x3 *api) +{ + return api->itf->rootdir_get_fd(api); +} + +/** + * Opens 'filename' within the root directory with 'flags' (see function openat) + * using the 'locale' definition (example: "jp,en-US") that can be NULL. + * + * The filename must be relative to the root of the bindings. + * + * The opening mode must be for read or write but not for O_CREAT. + * + * The definition of locales and of how files are searched can be checked + * here: https://www.w3.org/TR/widgets/#folder-based-localization + * and https://tools.ietf.org/html/rfc7231#section-5.3.5 + * + * @param api the api that queries the file + * @param filename the relative path to the file to open + * @param flags the flags for opening as for C function 'open' + * @param locale string indicating how to search content, can be NULL + * + * @return the file descriptor or -1 in case of error and errno is set with the + * error indication. + * + * @see open + * @see afb_api_x3_rootdir_get_fd + */ +static inline +int afb_api_x3_rootdir_open_locale(struct afb_api_x3 *api, const char *filename, int flags, const char *locale) +{ + return api->itf->rootdir_open_locale(api, filename, flags, locale); +} + +/** + * Queue the job defined by 'callback' and 'argument' for being executed asynchronously + * in this thread (later) or in an other thread. + * + * If 'group' is not NULL, the jobs queued with a same value (as the pointer value 'group') + * are executed in sequence in the order of there submission. + * + * If 'timeout' is not 0, it represent the maximum execution time for the job in seconds. + * At first, the job is called with 0 as signum and the given argument. + * + * The job is executed with the monitoring of its time and some signals like SIGSEGV and + * SIGFPE. When a such signal is catched, the job is terminated and reexecuted but with + * signum being the signal number (SIGALRM when timeout expired). + * + * When executed, the callback function receives 2 arguments: + * + * - int signum: the signal catched if any or zero at the beginning + * - void *arg: the parameter 'argument' + * + * A typical implmentation of the job callback is: + * + * ```C + * void my_job_cb(int signum, void *arg) + * { + * struct myarg_t *myarg = arg; + * if (signum) + * AFB_API_ERROR(myarg->api, "job interupted with signal %s", strsignal(signum)); + * else + * really_do_my_job(myarg); + * } + * ``` + * + * @param api the api that queue the job + * @param callback the job as a callback function + * @param argument the argument to pass to the queued job + * @param group the group of the job, NULL if no group + * @param timeout the timeout of execution of the job + * + * @return 0 in case of success or -1 in case of error with errno set appropriately. + */ +static inline +int afb_api_x3_queue_job(struct afb_api_x3 *api, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout) +{ + return api->itf->queue_job(api, callback, argument, group, timeout); +} + +/** + * Tells that it requires the API of "name" to exist + * and if 'initialized' is not null to be initialized. + * Calling this function is only allowed within init. + * + * A single request allows to require multiple apis. + * + * @param api the api that requires the other api by its name + * @param name a space separated list of the names of the required api + * @param initialized if zero, the api is just required to exist. If not zero, + * the api is required to exist and to be initialized. + * + * @return 0 in case of success or -1 in case of error with errno set appropriately. + */ +static inline +int afb_api_x3_require_api(struct afb_api_x3 *api, const char *name, int initialized) +{ + return api->itf->require_api(api, name, initialized); +} + +/** + * Create an aliased name 'as_name' for the api 'name'. + * Calling this function is only allowed within preinit. + * + * @param api the api that requires the aliasing + * @param name the api to alias + * @param as_name the aliased name of the aliased api + * + * @return 0 in case of success or -1 in case of error with errno set appropriately. + */ +static inline +int afb_api_x3_add_alias(struct afb_api_x3 *api, const char *name, const char *as_name) +{ + return api->itf->add_alias(api, name, as_name); +} + +/** + * Broadcasts widely the event of 'name' with the data 'object'. + * 'object' can be NULL. + * + * For convenience, the function calls 'json_object_put' for 'object'. + * Thus, in the case where 'object' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * Calling this function is only forbidden during preinit. + * + * The event sent as the name API/name where API is the name of the + * api. + * + * @param api the api that broadcast the event + * @param name the event name suffix + * @param object the object that comes with the event + * + * @return the count of clients that received the event. + */ +static inline +int afb_api_x3_broadcast_event(struct afb_api_x3 *api, const char *name, struct json_object *object) +{ + return api->itf->event_broadcast(api, name, object); +} + +/** + * Creates an event of 'name' and returns it. + * + * Calling this function is only forbidden during preinit. + * + * See afb_event_is_valid to check if there is an error. + * + * The event created as the name API/name where API is the name of the + * api. + * + * @param api the api that creates the event + * @param name the event name suffix + * + * @return the created event. Use the function afb_event_is_valid to check + * whether the event is valid (created) or not (error as reported by errno). + * + * @see afb_event_is_valid + */ +static inline +struct afb_event_x2 *afb_api_x3_make_event_x2(struct afb_api_x3 *api, const char *name) +{ + return api->itf->event_make(api, name); +} + +/** + * @deprecated try to use @ref afb_api_x3_call instead + * + * * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. + * The result of the call is delivered to the 'callback' function with the 'callback_closure'. + * + * For convenience, the function calls 'json_object_put' for 'args'. + * Thus, in the case where 'args' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * The 'callback' receives 3 arguments: + * 1. 'closure' the user defined closure pointer 'closure', + * 2. 'status' a status being 0 on success or negative when an error occurred, + * 2. 'result' the resulting data as a JSON object. + * + * @param api The api + * @param apiname The api name of the method to call + * @param verb The verb name of the method to call + * @param args The arguments to pass to the method + * @param callback The to call on completion + * @param closure The closure to pass to the callback + * + * @see also 'afb_api_call' + * @see also 'afb_api_call_sync' + * @see also 'afb_api_call_sync_legacy' + * @see also 'afb_req_subcall' + * @see also 'afb_req_subcall_sync' + */ +static inline +void afb_api_x3_call_legacy( + struct afb_api_x3 *api, + const char *apiname, + const char *verb, + struct json_object *args, + void (*callback)(void *closure, int status, struct json_object *result, struct afb_api_x3 *api), + void *closure) +{ + api->itf->legacy_call(api, apiname, verb, args, callback, closure); +} + +/** + * @deprecated try to use @ref afb_api_x3_call_sync instead + * + * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. + * 'result' will receive the response. + * + * For convenience, the function calls 'json_object_put' for 'args'. + * Thus, in the case where 'args' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * @param api The api + * @param apiname The api name of the method to call + * @param verb The verb name of the method to call + * @param args The arguments to pass to the method + * @param result Where to store the result - should call json_object_put on it - + * + * @returns 0 in case of success or a negative value in case of error. + * + * @see also 'afb_api_call' + * @see also 'afb_api_call_sync' + * @see also 'afb_api_call_legacy' + * @see also 'afb_req_subcall' + * @see also 'afb_req_subcall_sync' + */ +static inline +int afb_api_x3_call_sync_legacy( + struct afb_api_x3 *api, + const char *apiname, + const char *verb, + struct json_object *args, + struct json_object **result) +{ + return api->itf->legacy_call_sync(api, apiname, verb, args, result); +} + +/** + * Creates a new api of name 'apiname' briefly described by 'info' (that can + * be NULL). + * + * When the pre-initialization function is given, it is a function that + * receives 2 parameters: + * + * - the closure as given in the call + * - the created api that can be initialised + * + * This pre-initialization function must return a negative value to abort + * the creation of the api. Otherwise, it returns a non-negative value to + * continue. + * + * @param api the api that creates the other one + * @param apiname the name of the new api + * @param info the brief description of the new api (can be NULL) + * @param noconcurrency zero or not zero whether the new api is reentrant or not + * @param preinit the pre-initialization function if any (can be NULL) + * @param closure the closure for the pre-initialization \ref preinit + * + * @return 0 in case of success or -1 on failure with errno set + * + * @see afb_api_x3_delete_api + */ +static inline +struct afb_api_x3 *afb_api_x3_new_api( + struct afb_api_x3 *api, + const char *apiname, + const char *info, + int noconcurrency, + int (*preinit)(void*, struct afb_api_x3 *), + void *closure) +{ + return api->itf->api_new_api(api, apiname, info, noconcurrency, preinit, closure); +} + +/** + * @deprecated use @ref afb_api_x3_set_verbs_v3 instead + * + * Set the verbs of the 'api' using description of verbs of the api v2 + * + * @param api the api that will get the verbs + * @param verbs the array of verbs to add terminated with an item with name=NULL + * + * @return 0 in case of success or -1 on failure with errno set + * + * @see afb_verb_v2 + * @see afb_api_x3_add_verb + * @see afb_api_x3_set_verbs_v3 + */ +static inline +int afb_api_x3_set_verbs_v2( + struct afb_api_x3 *api, + const struct afb_verb_v2 *verbs) +{ + return api->itf->api_set_verbs_v2(api, verbs); +} + +/** + * Add one verb to the dynamic set of the api + * + * @param api the api to change + * @param verb name of the verb + * @param info brief description of the verb, can be NULL + * @param callback callback function implementing the verb + * @param vcbdata data for the verb callback, available through req + * @param auth required authorization, can be NULL + * @param session authorization and session requirements of the verb + * @param glob is the verb glob name + * + * @return 0 in case of success or -1 on failure with errno set + * + * @see afb_verb_v3 + * @see afb_api_x3_del_verb + * @see afb_api_x3_set_verbs_v3 + * @see fnmatch for matching names using glob + */ +static inline +int afb_api_x3_add_verb( + struct afb_api_x3 *api, + const char *verb, + const char *info, + void (*callback)(struct afb_req_x2 *req), + void *vcbdata, + const struct afb_auth *auth, + uint32_t session, + int glob) +{ + return api->itf->api_add_verb(api, verb, info, callback, vcbdata, auth, session, glob); +} + +/** + * Delete one verb from the dynamic set of the api + * + * @param api the api to change + * @param verb name of the verb to delete + * @param vcbdata if not NULL will receive the vcbdata of the deleted verb + * + * @return 0 in case of success or -1 on failure with errno set + * + * @see afb_api_x3_add_verb + */ +static inline +int afb_api_x3_del_verb( + struct afb_api_x3 *api, + const char *verb, + void **vcbdata) +{ + return api->itf->api_del_verb(api, verb, vcbdata); +} + +/** + * Set the callback 'onevent' to process events in the name of the 'api'. + * + * This setting can be done statically using the global variable + * @ref afbBindingV3. + * + * This function replace any previously global event callback set. + * + * When an event is received, the callback 'onevent' is called with 3 parameters + * + * - the api that recorded the event handler + * - the full name of the event + * - the companion JSON object of the event + * + * @param api the api that wants to process events + * @param onevent the callback function that will process events (can be NULL + * to remove event callback) + * + * @return 0 in case of success or -1 on failure with errno set + * + * @see afbBindingV3 + * @see afb_binding_v3 + * @see afb_api_x3_event_handler_add + * @see afb_api_x3_event_handler_del + */ +static inline +int afb_api_x3_on_event( + struct afb_api_x3 *api, + void (*onevent)(struct afb_api_x3 *api, const char *event, struct json_object *object)) +{ + return api->itf->api_set_on_event(api, onevent); +} + +/** + * Set the callback 'oninit' to process initialization of the 'api'. + * + * This setting can be done statically using the global variable + * @ref afbBindingV3 + * + * This function replace any previously initialization callback set. + * + * This function is only valid during the pre-initialization stage. + * + * The callback initialization function will receive one argument: the api + * to initialize. + * + * @param api the api that wants to process events + * @param oninit the callback function that initialize the api + * + * @return 0 in case of success or -1 on failure with errno set + * + * @see afbBindingV3 + * @see afb_binding_v3 + */ +static inline +int afb_api_x3_on_init( + struct afb_api_x3 *api, + int (*oninit)(struct afb_api_x3 *api)) +{ + return api->itf->api_set_on_init(api, oninit); +} + +/** + * Seal the api. After a call to this function the api can not be modified + * anymore. + * + * @param api the api to be sealed + */ +static inline +void afb_api_x3_seal( + struct afb_api_x3 *api) +{ + api->itf->api_seal(api); +} + +/** + * Set the verbs of the 'api' using description of verbs of the api v2 + * + * @param api the api that will get the verbs + * @param verbs the array of verbs to add terminated with an item with name=NULL + * + * @return 0 in case of success or -1 on failure with errno set + * + * @see afb_verb_v3 + * @see afb_api_x3_add_verb + * @see afb_api_x3_del_verb + */ +static inline +int afb_api_x3_set_verbs_v3( + struct afb_api_x3 *api, + const struct afb_verb_v3 *verbs) +{ + return api->itf->api_set_verbs_v3(api, verbs); +} + +/** + * Add a specific event handler for the api + * + * The handler callback is called when an event matching the given pattern + * is received (it is received if broadcasted or after subscription through + * a call or a subcall). + * + * The handler callback receive 4 arguments: + * + * - the closure given here + * - the event full name + * - the companion JSON object of the event + * - the api that subscribed the event + * + * @param api the api that creates the handler + * @param pattern the global pattern of the event to handle + * @param callback the handler callback function + * @param closure the closure of the handler + * + * @return 0 in case of success or -1 on failure with errno set + * + * @see afb_api_x3_on_event + * @see afb_api_x3_event_handler_del + */ +static inline +int afb_api_x3_event_handler_add( + struct afb_api_x3 *api, + const char *pattern, + void (*callback)(void *, const char*, struct json_object*, struct afb_api_x3*), + void *closure) +{ + return api->itf->event_handler_add(api, pattern, callback, closure); +} + +/** + * Delete a specific event handler for the api + * + * @param api the api that the handler belongs to + * @param pattern the global pattern of the handler to remove + * @param closure if not NULL it will receive the closure set to the handler + * + * @return 0 in case of success or -1 on failure with errno set + * + * @see afb_api_x3_on_event + * @see afb_api_x3_event_handler_add + */ +static inline +int afb_api_x3_event_handler_del( + struct afb_api_x3 *api, + const char *pattern, + void **closure) +{ + return api->itf->event_handler_del(api, pattern, closure); +} + +/** + * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. + * The result of the call is delivered to the 'callback' function with the 'callback_closure'. + * + * For convenience, the function calls 'json_object_put' for 'args'. + * Thus, in the case where 'args' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * The 'callback' receives 5 arguments: + * 1. 'closure' the user defined closure pointer 'closure', + * 2. 'object' a JSON object returned (can be NULL) + * 3. 'error' a string not NULL in case of error but NULL on success + * 4. 'info' a string handling some info (can be NULL) + * 5. 'api' the api + * + * @param api The api that makes the call + * @param apiname The api name of the method to call + * @param verb The verb name of the method to call + * @param args The arguments to pass to the method + * @param callback The to call on completion + * @param closure The closure to pass to the callback + * + * + * @see afb_req_subcall + * @see afb_req_subcall_sync + * @see afb_api_x3_call_sync + */ +static inline +void afb_api_x3_call( + struct afb_api_x3 *api, + const char *apiname, + const char *verb, + struct json_object *args, + void (*callback)(void *closure, struct json_object *object, const char *error, const char * info, struct afb_api_x3 *api), + void *closure) +{ + api->itf->call(api, apiname, verb, args, callback, closure); +} + +/** + * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. + * 'result' will receive the response. + * + * For convenience, the function calls 'json_object_put' for 'args'. + * Thus, in the case where 'args' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * @param api The api that makes the call + * @param apiname The api name of the method to call + * @param verb The verb name of the method to call + * @param args The arguments to pass to the method + * @param object Where to store the returned object - should call json_object_put on it - can be NULL + * @param error Where to store the copied returned error - should call free on it - can be NULL + * @param info Where to store the copied returned info - should call free on it - can be NULL + * + * @returns 0 in case of success or a negative value in case of error. + * + * @see afb_req_subcall + * @see afb_req_subcall_sync + * @see afb_api_x3_call + */ +static inline +int afb_api_x3_call_sync( + struct afb_api_x3 *api, + const char *apiname, + const char *verb, + struct json_object *args, + struct json_object **object, + char **error, + char **info) +{ + return api->itf->call_sync(api, apiname, verb, args, object, error, info); +} + +/** + * Tells that the api provides a class of features. Classes are intended to + * allow ordering of initializations: apis that provides a given class are + * initialized before apis requiring it. + * + * This function is only valid during the pre-initialization stage. + * + * @param api the api that provides the classes + * @param name a space separated list of the names of the provided classes + * + * @returns 0 in case of success or a negative value in case of error. + * + * @see afb_api_x3_require_class + */ +static inline +int afb_api_x3_provide_class( + struct afb_api_x3 *api, + const char *name) +{ + return api->itf->class_provide(api, name); +} + +/** + * Tells that the api requires a set of class features. Classes are intended to + * allow ordering of initializations: apis that provides a given class are + * initialized before apis requiring it. + * + * This function is only valid during the pre-initialization stage. + * + * @param api the api that requires the classes + * @param name a space separated list of the names of the requireded classes + * + * @returns 0 in case of success or a negative value in case of error. + * + * @see afb_api_x3_provide_class + */ +static inline +int afb_api_x3_require_class( + struct afb_api_x3 *api, + const char *name) +{ + return api->itf->class_require(api, name); +} + +/** + * Delete the given api. + * + * It is of the responsibility of the caller to don't used the deleted api + * anymore after this function returned. + * + * @param api the api to delete + * + * @returns 0 in case of success or a negative value in case of error. + * + * @see afb_api_x3_new_api + */ +static inline +int afb_api_x3_delete_api( + struct afb_api_x3 *api) +{ + return api->itf->delete_api(api); +} diff --git a/include/afb/afb-arg.h b/include/afb/afb-arg.h new file mode 100644 index 00000000..de3fb9b5 --- /dev/null +++ b/include/afb/afb-arg.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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 + +/** + * Describes an argument (or parameter) of a request. + * + * @see afb_req_get + */ +struct afb_arg +{ + const char *name; /**< name of the argument or NULL if invalid */ + const char *value; /**< string representation of the value of the argument */ + /**< original filename of the argument if path != NULL */ + const char *path; /**< if not NULL, path of the received file for the argument */ + /**< when the request is finalized this file is removed */ +}; + diff --git a/include/afb/afb-auth.h b/include/afb/afb-auth.h index da4f8be8..3ce78666 100644 --- a/include/afb/afb-auth.h +++ b/include/afb/afb-auth.h @@ -17,29 +17,58 @@ #pragma once -/* - * Enum for Session/Token/Assurance middleware. +/** + * Enumeration for authority (Session/Token/Assurance) definitions. + * + * @see afb_auth */ enum afb_auth_type { - afb_auth_No = 0, /** never authorized, no data */ - afb_auth_Token, /** authorized if token valid, no data */ - afb_auth_LOA, /** authorized if LOA greater than data 'loa' */ - afb_auth_Permission, /** authorized if permission 'text' is granted */ - afb_auth_Or, /** authorized if 'first' or 'next' is authorized */ - afb_auth_And, /** authorized if 'first' and 'next' are authorized */ - afb_auth_Not, /** authorized if 'first' is not authorized */ - afb_auth_Yes /** always authorized, no data */ + /** never authorized, no data */ + afb_auth_No = 0, + + /** authorized if token valid, no data */ + afb_auth_Token, + + /** authorized if LOA greater than data 'loa' */ + afb_auth_LOA, + + /** authorized if permission 'text' is granted */ + afb_auth_Permission, + + /** authorized if 'first' or 'next' is authorized */ + afb_auth_Or, + + /** authorized if 'first' and 'next' are authorized */ + afb_auth_And, + + /** authorized if 'first' is not authorized */ + afb_auth_Not, + + /** always authorized, no data */ + afb_auth_Yes }; +/** + * Definition of an authorization entry + */ struct afb_auth { + /** type of entry @see afb_auth_type */ enum afb_auth_type type; + union { + /** text when @ref type == @ref afb_auth_Permission */ const char *text; + + /** level of assurancy when @ref type == @ref afb_auth_LOA */ unsigned loa; + + /** first child when @ref type in { @ref afb_auth_Or, @ref afb_auth_And, @ref afb_auth_Not } */ const struct afb_auth *first; }; + + /** second child when @ref type in { @ref afb_auth_Or, @ref afb_auth_And } */ const struct afb_auth *next; }; diff --git a/include/afb/afb-binding-postdefs.h b/include/afb/afb-binding-postdefs.h new file mode 100644 index 00000000..93cd46ef --- /dev/null +++ b/include/afb/afb-binding-postdefs.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2018 "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 + +typedef enum afb_auth_type afb_auth_type_t; +typedef struct afb_auth afb_auth_t; +typedef struct afb_arg afb_arg_t; + +#if AFB_BINDING_VERSION == 1 + +typedef struct afb_verb_desc_v1 afb_verb_t; +typedef struct afb_binding_v1 afb_binding_t; +typedef struct afb_binding_interface_v1 afb_binding_interface_v1; + +typedef struct afb_daemon_x1 afb_daemon_t; +typedef struct afb_service_x1 afb_service_t; + +typedef struct afb_event_x1 afb_event_t; +typedef struct afb_req_x1 afb_req_t; + +typedef struct afb_stored_req afb_stored_req_t; + +#ifndef __cplusplus +typedef struct afb_event_x1 afb_event; +typedef struct afb_req_x1 afb_req; +typedef struct afb_stored_req afb_stored_req; +#endif + +#endif + +#if AFB_BINDING_VERSION == 2 + +typedef struct afb_verb_v2 afb_verb_t; +typedef struct afb_binding_v2 afb_binding_t; + +typedef struct afb_daemon afb_daemon_t; +typedef struct afb_event afb_event_t; +typedef struct afb_req afb_req_t; +typedef struct afb_stored_req afb_stored_req_t; +typedef struct afb_service afb_service_t; + +#define afbBindingExport afbBindingV2 + +#ifndef __cplusplus +typedef struct afb_verb_v2 afb_verb_v2; +typedef struct afb_binding_v2 afb_binding_v2; +typedef struct afb_event_x1 afb_event; +typedef struct afb_req_x1 afb_req; +typedef struct afb_stored_req afb_stored_req; +#endif + +#endif + +#if AFB_BINDING_VERSION == 3 + +typedef struct afb_verb_v3 afb_verb_t; +typedef struct afb_binding_v3 afb_binding_t; + +typedef struct afb_event_x2 *afb_event_t; +typedef struct afb_req_x2 *afb_req_t; +typedef struct afb_api_x3 *afb_api_t; + +#define afbBindingExport afbBindingV3 + +/* compatibility with previous versions */ + +typedef struct afb_api_x3 *afb_daemon_t; +typedef struct afb_api_x3 *afb_service_t; + +#endif + + +#if defined(AFB_BINDING_WANT_DYNAPI) +typedef struct afb_dynapi *afb_dynapi_t; +typedef struct afb_request *afb_request_t; +typedef struct afb_eventid *afb_eventid_t; +#endif
\ No newline at end of file diff --git a/include/afb/afb-binding-predefs.h b/include/afb/afb-binding-predefs.h new file mode 100644 index 00000000..f1765edb --- /dev/null +++ b/include/afb/afb-binding-predefs.h @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2018 "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 + +/******************************************************************************/ + +#if AFB_BINDING_VERSION == 1 || AFB_BINDING_VERSION == 2 + +#define afb_req afb_req_x1 +#define afb_req_is_valid afb_req_x1_is_valid +#define afb_req_get afb_req_x1_get +#define afb_req_value afb_req_x1_value +#define afb_req_path afb_req_x1_path +#define afb_req_json afb_req_x1_json +#define afb_req_reply afb_req_x1_reply +#define afb_req_reply_f afb_req_x1_reply_f +#define afb_req_reply_v afb_req_x1_reply_v +#define afb_req_success(r,o,i) afb_req_x1_reply(r,o,0,i) +#define afb_req_success_f(r,o,...) afb_req_x1_reply_f(r,o,0,__VA_ARGS__) +#define afb_req_success_v(r,o,f,v) afb_req_x1_reply_v(r,o,0,f,v) +#define afb_req_fail(r,e,i) afb_req_x1_reply(r,0,e,i) +#define afb_req_fail_f(r,e,...) afb_req_x1_reply_f(r,0,e,__VA_ARGS__) +#define afb_req_fail_v(r,e,f,v) afb_req_x1_reply_v(r,0,e,f,v) +#define afb_req_context_get afb_req_x1_context_get +#define afb_req_context_set afb_req_x1_context_set +#define afb_req_context afb_req_x1_context +#define afb_req_context_make afb_req_x1_context_make +#define afb_req_context_clear afb_req_x1_context_clear +#define afb_req_addref afb_req_x1_addref +#define afb_req_unref afb_req_x1_unref +#define afb_req_session_close afb_req_x1_session_close +#define afb_req_session_set_LOA afb_req_x1_session_set_LOA +#define afb_req_subscribe afb_req_x1_subscribe +#define afb_req_unsubscribe afb_req_x1_unsubscribe +#define afb_req_subcall afb_req_x1_subcall +#define afb_req_subcall_req afb_req_x1_subcall_req +#define afb_req_subcall_sync afb_req_x1_subcall_sync +#define afb_req_verbose afb_req_x1_verbose +#define afb_req_has_permission afb_req_x1_has_permission +#define afb_req_get_application_id afb_req_x1_get_application_id +#define afb_req_get_uid afb_req_x1_get_uid +#define afb_req_get_client_info afb_req_x1_get_client_info + +#define afb_event afb_event_x1 +#define afb_event_to_event_x2 afb_event_x1_to_event_x2 +#define afb_event_is_valid afb_event_x1_is_valid +#define afb_event_broadcast afb_event_x1_broadcast +#define afb_event_push afb_event_x1_push +#define afb_event_drop afb_event_x1_unref +#define afb_event_name afb_event_x1_name +#define afb_event_unref afb_event_x1_unref +#define afb_event_addref afb_event_x1_addref + +#define afb_service afb_service_x1 +#define afb_daemon afb_daemon_x1 + +#define _AFB_SYSLOG_LEVEL_EMERGENCY_ AFB_SYSLOG_LEVEL_EMERGENCY +#define _AFB_SYSLOG_LEVEL_ALERT_ AFB_SYSLOG_LEVEL_ALERT +#define _AFB_SYSLOG_LEVEL_CRITICAL_ AFB_SYSLOG_LEVEL_CRITICAL +#define _AFB_SYSLOG_LEVEL_ERROR_ AFB_SYSLOG_LEVEL_ERROR +#define _AFB_SYSLOG_LEVEL_WARNING_ AFB_SYSLOG_LEVEL_WARNING +#define _AFB_SYSLOG_LEVEL_NOTICE_ AFB_SYSLOG_LEVEL_NOTICE +#define _AFB_SYSLOG_LEVEL_INFO_ AFB_SYSLOG_LEVEL_INFO +#define _AFB_SYSLOG_LEVEL_DEBUG_ AFB_SYSLOG_LEVEL_DEBUG + +#endif + +/******************************************************************************/ +#if AFB_BINDING_VERSION == 1 + +#define afb_req_store afb_req_x1_store_v1 +#define afb_req_unstore afb_req_x1_unstore_v1 + +#define afb_binding afb_binding_v1 +#define afb_binding_interface afb_binding_interface_v1 + +#define afb_daemon_get_event_loop afb_daemon_get_event_loop_v1 +#define afb_daemon_get_user_bus afb_daemon_get_user_bus_v1 +#define afb_daemon_get_system_bus afb_daemon_get_system_bus_v1 +#define afb_daemon_broadcast_event afb_daemon_broadcast_event_v1 +#define afb_daemon_make_event afb_daemon_make_event_v1 +#define afb_daemon_verbose afb_daemon_verbose_v1 +#define afb_daemon_rootdir_get_fd afb_daemon_rootdir_get_fd_v1 +#define afb_daemon_rootdir_open_locale afb_daemon_rootdir_open_locale_v1 +#define afb_daemon_queue_job afb_daemon_queue_job_v1 +#define afb_daemon_require_api afb_daemon_require_api_v1 +#define afb_daemon_rename_api afb_daemon_add_alias_v1 + +#define afb_service_call afb_service_call_v1 +#define afb_service_call_sync afb_service_call_sync_v1 + +# define AFB_ERROR AFB_ERROR_V1 +# define AFB_WARNING AFB_WARNING_V1 +# define AFB_NOTICE AFB_NOTICE_V1 +# define AFB_INFO AFB_INFO_V1 +# define AFB_DEBUG AFB_DEBUG_V1 + +# define AFB_REQ_ERROR AFB_REQ_ERROR_V1 +# define AFB_REQ_WARNING AFB_REQ_WARNING_V1 +# define AFB_REQ_NOTICE AFB_REQ_NOTICE_V1 +# define AFB_REQ_INFO AFB_REQ_INFO_V1 +# define AFB_REQ_DEBUG AFB_REQ_DEBUG_V1 + +#define AFB_REQ_VERBOSE AFB_REQ_VERBOSE_V1 + +# define AFB_SESSION_NONE AFB_SESSION_NONE_X1 +# define AFB_SESSION_CREATE AFB_SESSION_CREATE_X1 +# define AFB_SESSION_CLOSE AFB_SESSION_CLOSE_X1 +# define AFB_SESSION_RENEW AFB_SESSION_RENEW_X1 +# define AFB_SESSION_CHECK AFB_SESSION_CHECK_X1 + +# define AFB_SESSION_LOA_GE AFB_SESSION_LOA_GE_X1 +# define AFB_SESSION_LOA_LE AFB_SESSION_LOA_LE_X1 +# define AFB_SESSION_LOA_EQ AFB_SESSION_LOA_EQ_X1 + +# define AFB_SESSION_LOA_SHIFT AFB_SESSION_LOA_SHIFT_X1 +# define AFB_SESSION_LOA_MASK AFB_SESSION_LOA_MASK_X1 + +# define AFB_SESSION_LOA_0 AFB_SESSION_LOA_0_X1 +# define AFB_SESSION_LOA_1 AFB_SESSION_LOA_1_X1 +# define AFB_SESSION_LOA_2 AFB_SESSION_LOA_2_X1 +# define AFB_SESSION_LOA_3 AFB_SESSION_LOA_3_X1 +# define AFB_SESSION_LOA_4 AFB_SESSION_LOA_4_X1 + +# define AFB_SESSION_LOA_LE_0 AFB_SESSION_LOA_LE_0_X1 +# define AFB_SESSION_LOA_LE_1 AFB_SESSION_LOA_LE_1_X1 +# define AFB_SESSION_LOA_LE_2 AFB_SESSION_LOA_LE_2_X1 +# define AFB_SESSION_LOA_LE_3 AFB_SESSION_LOA_LE_3_X1 + +# define AFB_SESSION_LOA_EQ_0 AFB_SESSION_LOA_EQ_0_X1 +# define AFB_SESSION_LOA_EQ_1 AFB_SESSION_LOA_EQ_1_X1 +# define AFB_SESSION_LOA_EQ_2 AFB_SESSION_LOA_EQ_2_X1 +# define AFB_SESSION_LOA_EQ_3 AFB_SESSION_LOA_EQ_3_X1 + +# define AFB_SESSION_LOA_GE_0 AFB_SESSION_LOA_GE_0_X1 +# define AFB_SESSION_LOA_GE_1 AFB_SESSION_LOA_GE_1_X1 +# define AFB_SESSION_LOA_GE_2 AFB_SESSION_LOA_GE_2_X1 +# define AFB_SESSION_LOA_GE_3 AFB_SESSION_LOA_GE_3_X1 + +#endif + +/******************************************************************************/ +#if AFB_BINDING_VERSION == 2 + +#define afb_req_store afb_req_x1_store_v2 +#define afb_req_unstore afb_daemon_unstore_req_v2 + +#define afb_binding afb_binding_v2 + +#define afb_get_verbosity afb_get_verbosity_v2 +#define afb_get_daemon afb_get_daemon_v2 +#define afb_get_service afb_get_service_v2 + +#define afb_daemon_get_event_loop afb_daemon_get_event_loop_v2 +#define afb_daemon_get_user_bus afb_daemon_get_user_bus_v2 +#define afb_daemon_get_system_bus afb_daemon_get_system_bus_v2 +#define afb_daemon_broadcast_event afb_daemon_broadcast_event_v2 +#define afb_daemon_make_event afb_daemon_make_event_v2 +#define afb_daemon_verbose afb_daemon_verbose_v2 +#define afb_daemon_rootdir_get_fd afb_daemon_rootdir_get_fd_v2 +#define afb_daemon_rootdir_open_locale afb_daemon_rootdir_open_locale_v2 +#define afb_daemon_queue_job afb_daemon_queue_job_v2 +#define afb_daemon_unstore_req afb_daemon_unstore_req_v2 +#define afb_daemon_require_api afb_daemon_require_api_v2 +#define afb_daemon_rename_api(x) afb_daemon_add_alias_v2(0,x) +#define afb_daemon_add_alias afb_daemon_add_alias_v2 + +#define afb_service_call afb_service_call_v2 +#define afb_service_call_sync afb_service_call_sync_v2 + +#define AFB_ERROR AFB_ERROR_V2 +#define AFB_WARNING AFB_WARNING_V2 +#define AFB_NOTICE AFB_NOTICE_V2 +#define AFB_INFO AFB_INFO_V2 +#define AFB_DEBUG AFB_DEBUG_V2 + +#define AFB_REQ_ERROR AFB_REQ_ERROR_V2 +#define AFB_REQ_WARNING AFB_REQ_WARNING_V2 +#define AFB_REQ_NOTICE AFB_REQ_NOTICE_V2 +#define AFB_REQ_INFO AFB_REQ_INFO_V2 +#define AFB_REQ_DEBUG AFB_REQ_DEBUG_V2 + +#define AFB_REQ_VERBOSE AFB_REQ_VERBOSE_V2 + +#endif + +/******************************************************************************/ +#if AFB_BINDING_VERSION == 2 || AFB_BINDING_VERSION == 3 + +#define AFB_SESSION_NONE AFB_SESSION_NONE_X2 +#define AFB_SESSION_CLOSE AFB_SESSION_CLOSE_X2 +#define AFB_SESSION_RENEW AFB_SESSION_REFRESH_X2 +#define AFB_SESSION_REFRESH AFB_SESSION_REFRESH_X2 +#define AFB_SESSION_CHECK AFB_SESSION_CHECK_X2 + +#define AFB_SESSION_LOA_MASK AFB_SESSION_LOA_MASK_X2 + +#define AFB_SESSION_LOA_0 AFB_SESSION_LOA_0_X2 +#define AFB_SESSION_LOA_1 AFB_SESSION_LOA_1_X2 +#define AFB_SESSION_LOA_2 AFB_SESSION_LOA_2_X2 +#define AFB_SESSION_LOA_3 AFB_SESSION_LOA_3_X2 + +#endif + +/******************************************************************************/ +#if AFB_BINDING_VERSION == 2 + +#define AFB_SESSION_NONE_V2 AFB_SESSION_NONE_X2 +#define AFB_SESSION_CLOSE_V2 AFB_SESSION_CLOSE_X2 +#define AFB_SESSION_RENEW_V2 AFB_SESSION_REFRESH_X2 +#define AFB_SESSION_REFRESH_V2 AFB_SESSION_REFRESH_X2 +#define AFB_SESSION_CHECK_V2 AFB_SESSION_CHECK_X2 + +#define AFB_SESSION_LOA_MASK_V2 AFB_SESSION_LOA_MASK_X2 + +#define AFB_SESSION_LOA_0_V2 AFB_SESSION_LOA_0_X2 +#define AFB_SESSION_LOA_1_V2 AFB_SESSION_LOA_1_X2 +#define AFB_SESSION_LOA_2_V2 AFB_SESSION_LOA_2_X2 +#define AFB_SESSION_LOA_3_V2 AFB_SESSION_LOA_3_X2 + +#endif + +/******************************************************************************/ +#if AFB_BINDING_VERSION == 3 + +#define afb_req_x2 afb_req + +#define afb_req_x2_is_valid afb_req_is_valid +#define afb_req_x2_get_api afb_req_get_api +#define afb_req_x2_get_vcbdata afb_req_get_vcbdata +#define afb_req_x2_get_called_api afb_req_get_called_api +#define afb_req_x2_get_called_verb afb_req_get_called_verb +#define afb_req_x2_wants_log_level afb_req_wants_log_level + +#define afb_req_x2_get afb_req_get +#define afb_req_x2_value afb_req_value +#define afb_req_x2_path afb_req_path +#define afb_req_x2_json afb_req_json +#define afb_req_x2_reply afb_req_reply +#define afb_req_x2_reply_f afb_req_reply_f +#define afb_req_x2_reply_v afb_req_reply_v +#define afb_req_success(r,o,i) afb_req_reply(r,o,0,i) +#define afb_req_success_f(r,o,...) afb_req_reply_f(r,o,0,__VA_ARGS__) +#define afb_req_success_v(r,o,f,v) afb_req_reply_v(r,o,0,f,v) +#define afb_req_fail(r,e,i) afb_req_reply(r,0,e,i) +#define afb_req_fail_f(r,e,...) afb_req_reply_f(r,0,e,__VA_ARGS__) +#define afb_req_fail_v(r,e,f,v) afb_req_reply_v(r,0,e,f,v) +#define afb_req_x2_context_get afb_req_context_get +#define afb_req_x2_context_set afb_req_context_set +#define afb_req_x2_context afb_req_context +#define afb_req_x2_context_make afb_req_context_make +#define afb_req_x2_context_clear afb_req_context_clear +#define afb_req_x2_addref afb_req_addref +#define afb_req_x2_unref afb_req_unref +#define afb_req_x2_session_close afb_req_session_close +#define afb_req_x2_session_set_LOA afb_req_session_set_LOA +#define afb_req_x2_subscribe afb_req_subscribe +#define afb_req_x2_unsubscribe afb_req_unsubscribe +#define afb_req_x2_subcall afb_req_subcall +#define afb_req_x2_subcall_legacy afb_req_subcall_legacy +#define afb_req_x2_subcall_req afb_req_subcall_req +#define afb_req_x2_subcall_sync_legacy afb_req_subcall_sync_legacy +#define afb_req_x2_subcall_sync afb_req_subcall_sync +#define afb_req_x2_verbose afb_req_verbose +#define afb_req_x2_has_permission afb_req_has_permission +#define afb_req_x2_get_application_id afb_req_get_application_id +#define afb_req_x2_get_uid afb_req_get_uid +#define afb_req_x2_get_client_info afb_req_get_client_info + +#define afb_req_x2_subcall_catch_events afb_req_subcall_catch_events +#define afb_req_x2_subcall_pass_events afb_req_subcall_pass_events +#define afb_req_x2_subcall_on_behalf afb_req_subcall_on_behalf + +#define afb_event_x2 afb_event +#define afb_event_x2_is_valid afb_event_is_valid +#define afb_event_x2_broadcast afb_event_broadcast +#define afb_event_x2_push afb_event_push +#define afb_event_x2_name afb_event_name +#define afb_event_x2_unref afb_event_unref +#define afb_event_x2_addref afb_event_addref + +#define afb_api_x3 afb_api + +#define afb_api_x3_name afb_api_name +#define afb_api_x3_get_userdata afb_api_get_userdata +#define afb_api_x3_set_userdata afb_api_set_userdata +#define afb_api_x3_wants_log_level afb_api_wants_log_level + +#define afb_api_x3_verbose afb_api_verbose +#define afb_api_x3_get_event_loop afb_api_get_event_loop +#define afb_api_x3_get_user_bus afb_api_get_user_bus +#define afb_api_x3_get_system_bus afb_api_get_system_bus +#define afb_api_x3_rootdir_get_fd afb_api_rootdir_get_fd +#define afb_api_x3_rootdir_open_locale afb_api_rootdir_open_locale +#define afb_api_x3_queue_job afb_api_queue_job +#define afb_api_x3_require_api afb_api_require_api +#define afb_api_x3_broadcast_event afb_api_broadcast_event +#define afb_api_x3_make_event_x2 afb_api_make_event +#define afb_api_x3_call afb_api_call +#define afb_api_x3_call_sync afb_api_call_sync +#define afb_api_x3_call_legacy afb_api_call_legacy +#define afb_api_x3_call_sync_legacy afb_api_call_sync_legacy +#define afb_api_x3_new_api afb_api_new_api +#define afb_api_x3_set_verbs_v2 afb_api_set_verbs_v2 +#define afb_api_x3_add_verb afb_api_add_verb +#define afb_api_x3_del_verb afb_api_del_verb +#define afb_api_x3_on_event afb_api_on_event +#define afb_api_x3_on_init afb_api_on_init +#define afb_api_x3_seal afb_api_seal +#define afb_api_x3_add_alias afb_api_add_alias + +#define AFB_API_ERROR AFB_API_ERROR_V3 +#define AFB_API_WARNING AFB_API_WARNING_V3 +#define AFB_API_NOTICE AFB_API_NOTICE_V3 +#define AFB_API_INFO AFB_API_INFO_V3 +#define AFB_API_DEBUG AFB_API_DEBUG_V3 + +#define AFB_REQ_ERROR AFB_REQ_ERROR_V3 +#define AFB_REQ_WARNING AFB_REQ_WARNING_V3 +#define AFB_REQ_NOTICE AFB_REQ_NOTICE_V3 +#define AFB_REQ_INFO AFB_REQ_INFO_V3 +#define AFB_REQ_DEBUG AFB_REQ_DEBUG_V3 + +#define AFB_REQ_VERBOSE AFB_REQ_VERBOSE_V3 + +#define afb_stored_req afb_req_x2 +#define afb_req_store(x) afb_req_x2_addref(x) +#define afb_req_unstore(x) (x) + +#define afb_get_verbosity afb_get_verbosity_v3 +#define afb_get_logmask afb_get_logmask_v3 +#define afb_get_daemon afb_get_root_api_v3 +#define afb_get_service afb_get_root_api_v3 + +#define afb_daemon_get_event_loop afb_daemon_get_event_loop_v3 +#define afb_daemon_get_user_bus afb_daemon_get_user_bus_v3 +#define afb_daemon_get_system_bus afb_daemon_get_system_bus_v3 +#define afb_daemon_broadcast_event afb_daemon_broadcast_event_v3 +#define afb_daemon_make_event afb_daemon_make_event_v3 +#define afb_daemon_verbose afb_daemon_verbose_v3 +#define afb_daemon_rootdir_get_fd afb_daemon_rootdir_get_fd_v3 +#define afb_daemon_rootdir_open_locale afb_daemon_rootdir_open_locale_v3 +#define afb_daemon_queue_job afb_daemon_queue_job_v3 +#define afb_daemon_require_api afb_daemon_require_api_v3 +#define afb_daemon_add_alias afb_daemon_add_alias_v3 + +# define afb_service_call afb_service_call_v3 +# define afb_service_call_sync afb_service_call_sync_v3 + +# define AFB_ERROR AFB_ERROR_V3 +# define AFB_WARNING AFB_WARNING_V3 +# define AFB_NOTICE AFB_NOTICE_V3 +# define AFB_INFO AFB_INFO_V3 +# define AFB_DEBUG AFB_DEBUG_V3 + +#endif + diff --git a/include/afb/afb-binding-v1.h b/include/afb/afb-binding-v1.h index 9fb0ab89..3d5010d0 100644 --- a/include/afb/afb-binding-v1.h +++ b/include/afb/afb-binding-v1.h @@ -17,22 +17,27 @@ #pragma once -struct json_object; +/******************************************************************************/ -#include "afb-req.h" -#include "afb-event.h" -#include "afb-service-itf.h" -#include "afb-daemon-itf.h" +#include "afb-verbosity.h" +#include "afb-req-x1.h" +#include "afb-event-x1.h" +#include "afb-service-itf-x1.h" +#include "afb-daemon-itf-x1.h" #include "afb-req-v1.h" -#include "afb-session-v1.h" +#include "afb-session-x1.h" #include "afb-service-v1.h" #include "afb-daemon-v1.h" struct afb_binding_v1; struct afb_binding_interface_v1; -/* +/******************************************************************************/ + +/** + * @deprecated use bindings version 3 + * * Function for registering the binding * * A binding V1 MUST have an exported function of name @@ -57,7 +62,9 @@ struct afb_binding_interface_v1; */ extern const struct afb_binding_v1 *afbBindingV1Register (const struct afb_binding_interface_v1 *interface); -/* +/** + * @deprecated use bindings version 3 + * * When a binding have an exported implementation of the * function 'afbBindingV1ServiceInit', defined below, * the framework calls it for initialising the service after @@ -69,9 +76,11 @@ extern const struct afb_binding_v1 *afbBindingV1Register (const struct afb_bindi * The function should return 0 in case of success or, else, should return * a negative value. */ -extern int afbBindingV1ServiceInit(struct afb_service service); +extern int afbBindingV1ServiceInit(struct afb_service_x1 service); -/* +/** + * @deprecated use bindings version 3 + * * When a binding have an implementation of the function 'afbBindingV1ServiceEvent', * defined below, the framework calls that function for any broadcasted event or for * events that the service subscribed to in its name. @@ -82,30 +91,36 @@ extern int afbBindingV1ServiceInit(struct afb_service service); extern void afbBindingV1ServiceEvent(const char *event, struct json_object *object); -/* +/** + * @deprecated use bindings version 3 + * * Description of one verb of the API provided by the binding * This enumeration is valid for bindings of type version 1 */ struct afb_verb_desc_v1 { - const char *name; /* name of the verb */ - enum afb_session_flags_v1 session; /* authorisation and session requirements of the verb */ - void (*callback)(struct afb_req req); /* callback function implementing the verb */ - const char *info; /* textual description of the verb */ + const char *name; /**< name of the verb */ + enum afb_session_flags_x1 session; /**< authorisation and session requirements of the verb */ + void (*callback)(struct afb_req_x1 req);/**< callback function implementing the verb */ + const char *info; /**< textual description of the verb */ }; -/* +/** + * @deprecated use bindings version 3 + * * Description of the bindings of type version 1 */ struct afb_binding_desc_v1 { - const char *info; /* textual information about the binding */ - const char *prefix; /* required prefix name for the binding */ - const struct afb_verb_desc_v1 *verbs; /* array of descriptions of verbs terminated by a NULL name */ + const char *info; /**< textual information about the binding */ + const char *prefix; /**< required prefix name for the binding */ + const struct afb_verb_desc_v1 *verbs; /**< array of descriptions of verbs terminated by a NULL name */ }; -/* - * Definition of the type+versions of the binding. +/** + * @deprecated use bindings version 3 + * + * Definition of the type+versions of the binding version 1. * The definition uses hashes. */ enum afb_binding_type_v1 @@ -113,94 +128,107 @@ enum afb_binding_type_v1 AFB_BINDING_VERSION_1 = 123456789 }; -/* - * Description of a binding +/** + * @deprecated use bindings version 3 + * + * Description of a binding version 1 */ struct afb_binding_v1 { - enum afb_binding_type_v1 type; /* type of the binding */ + enum afb_binding_type_v1 type; /**< type of the binding */ union { - struct afb_binding_desc_v1 v1; /* description of the binding of type 1 */ + struct afb_binding_desc_v1 v1; /**< description of the binding of type 1 */ }; }; -/* - * config mode +/** + * @deprecated use bindings version 3 + * + * config mode for bindings version 1 */ enum afb_mode_v1 { - AFB_MODE_LOCAL = 0, /* run locally */ - AFB_MODE_REMOTE, /* run remotely */ - AFB_MODE_GLOBAL /* run either remotely or locally (DONT USE! reserved for future) */ + AFB_MODE_LOCAL = 0, /**< run locally */ + AFB_MODE_REMOTE, /**< run remotely */ + AFB_MODE_GLOBAL /**< run either remotely or locally (DONT USE! reserved for future) */ }; -/* - * Interface between the daemon and the binding. +/** + * @deprecated use bindings version 3 + * + * Interface between the daemon and the binding version 1. */ struct afb_binding_interface_v1 { - struct afb_daemon daemon; /* access to the daemon facilies */ - int verbosity; /* level of verbosity */ - enum afb_mode_v1 mode; /* run mode (local or remote) */ + struct afb_daemon_x1 daemon; /**< access to the daemon facilies */ + int verbosity; /**< level of verbosity */ + enum afb_mode_v1 mode; /**< run mode (local or remote) */ }; +/******************************************************************************/ /* * Macros for logging messages */ #if defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DATA) -# define _AFB_LOGGING_V1_(itf,vlevel,llevel,...) \ - do{ \ - if(itf->verbosity>=vlevel) {\ - if (llevel <= AFB_VERBOSITY_LEVEL_ERROR) \ - afb_daemon_verbose2_v1(itf->daemon,llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ - else \ - afb_daemon_verbose2_v1(itf->daemon,llevel,__FILE__,__LINE__,NULL,NULL); \ - } \ - }while(0) -# define _AFB_REQ_LOGGING_V1_(itf,vlevel,llevel,req,...) \ - do{ \ - if(itf->verbosity>=vlevel) \ - afb_req_verbose(req,llevel,__FILE__,__LINE__,NULL,NULL); \ - }while(0) +# define AFB_VERBOSE_V1(itf,level,...) \ + do { if(level <= AFB_VERBOSITY_LEVEL_ERROR) \ + afb_daemon_verbose2_v1(itf->daemon,level,__FILE__,__LINE__,NULL,__VA_ARGS__); \ + else afb_daemon_verbose2_v1(itf->daemon,level,__FILE__,__LINE__,NULL); } while(0) + +# define AFB_REQ_VERBOSE_V1(req,level,...) \ + do { if(level <= AFB_VERBOSITY_LEVEL_ERROR) \ + afb_req_x1_verbose(req,level,__FILE__,__LINE__,NULL,__VA_ARGS__); \ + else afb_req_x1_verbose(req,level,__FILE__,__LINE__,NULL); } while(0) #elif defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DETAILS) -# define _AFB_LOGGING_V1_(itf,vlevel,llevel,...) \ - do{ \ - if(itf->verbosity>=vlevel) \ - afb_daemon_verbose2_v1(itf->daemon,llevel,NULL,0,NULL,__VA_ARGS__); \ - }while(0) -# define _AFB_REQ_LOGGING_V1_(itf,vlevel,llevel,req,...) \ - do{ \ - if(itf->verbosity>=vlevel) \ - afb_req_verbose(req,llevel,NULL,0,NULL,__VA_ARGS__); \ - }while(0) +# define AFB_VERBOSE_V1(itf,level,...) \ + afb_daemon_verbose2_v1(itf->daemon,level,NULL,0,NULL,__VA_ARGS__) + +# define AFB_REQ_VERBOSE_V1(req,level,...) \ + afb_req_x1_verbose(req,level,NULL,0,NULL,__VA_ARGS__) #else -# define _AFB_LOGGING_V1_(itf,vlevel,llevel,...) \ - do{ \ - if(itf->verbosity>=vlevel) \ - afb_daemon_verbose2_v1(itf->daemon,llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ - }while(0) -# define _AFB_REQ_LOGGING_V1_(itf,vlevel,llevel,req,...) \ - do{ \ - if(itf->verbosity>=vlevel) \ - afb_req_verbose(req,llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ - }while(0) +# define AFB_VERBOSE_V1(itf,level,...) \ + afb_daemon_verbose2_v1(itf->daemon,level,__FILE__,__LINE__,__func__,__VA_ARGS__) + +# define AFB_REQ_VERBOSE_V1(req,level,...) \ + afb_req_x1_verbose(req,level,__FILE__,__LINE__,__func__,__VA_ARGS__) #endif -# include "afb-verbosity.h" -# define AFB_ERROR_V1(itf,...) _AFB_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_ERROR,_AFB_SYSLOG_LEVEL_ERROR_,__VA_ARGS__) -# define AFB_WARNING_V1(itf,...) _AFB_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_WARNING,_AFB_SYSLOG_LEVEL_WARNING_,__VA_ARGS__) -# define AFB_NOTICE_V1(itf,...) _AFB_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_NOTICE,_AFB_SYSLOG_LEVEL_NOTICE_,__VA_ARGS__) -# define AFB_INFO_V1(itf,...) _AFB_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_INFO,_AFB_SYSLOG_LEVEL_INFO_,__VA_ARGS__) -# define AFB_DEBUG_V1(itf,...) _AFB_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_DEBUG,_AFB_SYSLOG_LEVEL_DEBUG_,__VA_ARGS__) -# define AFB_REQ_ERROR_V1(itf,...) _AFB_REQ_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_ERROR,_AFB_SYSLOG_LEVEL_ERROR_,__VA_ARGS__) -# define AFB_REQ_WARNING_V1(itf,...) _AFB_REQ_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_WARNING,_AFB_SYSLOG_LEVEL_WARNING_,__VA_ARGS__) -# define AFB_REQ_NOTICE_V1(itf,...) _AFB_REQ_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_NOTICE,_AFB_SYSLOG_LEVEL_NOTICE_,__VA_ARGS__) -# define AFB_REQ_INFO_V1(itf,...) _AFB_REQ_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_INFO,_AFB_SYSLOG_LEVEL_INFO_,__VA_ARGS__) -# define AFB_REQ_DEBUG_V1(itf,...) _AFB_REQ_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_DEBUG,_AFB_SYSLOG_LEVEL_DEBUG_,__VA_ARGS__) +#define _AFB_LOGGING_V1_(itf,vlevel,llevel,...) \ + do{ if(itf->verbosity>=vlevel) AFB_VERBOSE_V1(itf,llevel,__VA_ARGS__); }while(0) +#define _AFB_REQ_LOGGING_V1_(itf,vlevel,llevel,req,...) \ + do{ if(itf->verbosity>=vlevel) AFB_REQ_VERBOSE_V1(itf,llevel,__VA_ARGS__); }while(0) + +# define AFB_ERROR_V1(itf,...) _AFB_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_ERROR,AFB_SYSLOG_LEVEL_ERROR,__VA_ARGS__) +# define AFB_WARNING_V1(itf,...) _AFB_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_WARNING,AFB_SYSLOG_LEVEL_WARNING,__VA_ARGS__) +# define AFB_NOTICE_V1(itf,...) _AFB_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_NOTICE,AFB_SYSLOG_LEVEL_NOTICE,__VA_ARGS__) +# define AFB_INFO_V1(itf,...) _AFB_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_INFO,AFB_SYSLOG_LEVEL_INFO,__VA_ARGS__) +# define AFB_DEBUG_V1(itf,...) _AFB_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_DEBUG,AFB_SYSLOG_LEVEL_DEBUG,__VA_ARGS__) + +# define AFB_REQ_ERROR_V1(itf,...) _AFB_REQ_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_ERROR,AFB_SYSLOG_LEVEL_ERROR,__VA_ARGS__) +# define AFB_REQ_WARNING_V1(itf,...) _AFB_REQ_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_WARNING,AFB_SYSLOG_LEVEL_WARNING,__VA_ARGS__) +# define AFB_REQ_NOTICE_V1(itf,...) _AFB_REQ_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_NOTICE,AFB_SYSLOG_LEVEL_NOTICE,__VA_ARGS__) +# define AFB_REQ_INFO_V1(itf,...) _AFB_REQ_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_INFO,AFB_SYSLOG_LEVEL_INFO,__VA_ARGS__) +# define AFB_REQ_DEBUG_V1(itf,...) _AFB_REQ_LOGGING_V1_(itf,AFB_VERBOSITY_LEVEL_DEBUG,AFB_SYSLOG_LEVEL_DEBUG,__VA_ARGS__) + +/******************************************************************************/ + +#if AFB_BINDING_VERSION == 1 && defined(AFB_BINDING_PRAGMA_KEEP_VERBOSE_UNPREFIX) +# define ERROR AFB_ERROR +# define WARNING AFB_WARNING +# define NOTICE AFB_NOTICE +# define INFO AFB_INFO +# define DEBUG AFB_DEBUG + +# define REQ_ERROR AFB_REQ_ERROR +# define REQ_WARNING AFB_REQ_WARNING +# define REQ_NOTICE AFB_REQ_NOTICE +# define REQ_INFO AFB_REQ_INFO +# define REQ_DEBUG AFB_REQ_DEBUG +#endif diff --git a/include/afb/afb-binding-v2.h b/include/afb/afb-binding-v2.h index 3aa61b23..1535f429 100644 --- a/include/afb/afb-binding-v2.h +++ b/include/afb/afb-binding-v2.h @@ -17,137 +17,156 @@ #pragma once -#include <stdint.h> +/******************************************************************************/ +#include "afb-verbosity.h" #include "afb-auth.h" -#include "afb-event.h" -#include "afb-req.h" -#include "afb-service-itf.h" -#include "afb-daemon-itf.h" +#include "afb-event-x1.h" +#include "afb-req-x1.h" +#include "afb-service-itf-x1.h" +#include "afb-daemon-itf-x1.h" #include "afb-req-v2.h" -#include "afb-session-v2.h" +#include "afb-session-x2.h" -struct json_object; +/******************************************************************************/ -/* - * Description of one verb of the API provided by the binding - * This enumeration is valid for bindings of type version 2 +/** + * @deprecated use bindings version 3 + * + * Description of one verb as provided for binding API version 2 */ struct afb_verb_v2 { - const char *verb; /* name of the verb, NULL only at end of the array */ - void (*callback)(struct afb_req req); /* callback function implementing the verb */ - const struct afb_auth *auth; /* required authorisation, can be NULL */ - const char *info; /* some info about the verb, can be NULL */ - uint32_t session; /* authorisation and session requirements of the verb */ + const char *verb; /**< name of the verb, NULL only at end of the array */ + void (*callback)(struct afb_req_x1 req);/**< callback function implementing the verb */ + const struct afb_auth *auth; /**< required authorisation, can be NULL */ + const char *info; /**< some info about the verb, can be NULL */ + uint32_t session; /**< authorisation and session requirements of the verb */ }; -/* +/** + * @deprecated use bindings version 3 + * * Description of the bindings of type version 2 */ struct afb_binding_v2 { - const char *api; /* api name for the binding */ - const char *specification; /* textual specification of the binding, can be NULL */ - const char *info; /* some info about the api, can be NULL */ - const struct afb_verb_v2 *verbs; /* array of descriptions of verbs terminated by a NULL name */ - int (*preinit)(); /* callback at load of the binding */ - int (*init)(); /* callback for starting the service */ - void (*onevent)(const char *event, struct json_object *object); /* callback for handling events */ - unsigned noconcurrency: 1; /* avoids concurrent requests to verbs */ + const char *api; /**< api name for the binding */ + const char *specification; /**< textual specification of the binding, can be NULL */ + const char *info; /**< some info about the api, can be NULL */ + const struct afb_verb_v2 *verbs; /**< array of descriptions of verbs terminated by a NULL name */ + int (*preinit)(); /**< callback at load of the binding */ + int (*init)(); /**< callback for starting the service */ + void (*onevent)(const char *event, struct json_object *object); /**< callback for handling events */ + unsigned noconcurrency: 1; /**< avoids concurrent requests to verbs */ }; +/** + * @deprecated use bindings version 3 + * + * structure for the global data of the binding + */ struct afb_binding_data_v2 { - int verbosity; /* level of verbosity */ - struct afb_daemon daemon; /* access to daemon APIs */ - struct afb_service service; /* access to service APIs */ + int verbosity; /**< level of verbosity */ + struct afb_daemon_x1 daemon; /**< access to daemon APIs */ + struct afb_service_x1 service; /**< access to service APIs */ }; -/* +/** + * @page validity-v2 Validity of a binding v2 + * * A binding V2 MUST have two exported symbols of name: * - * - afbBindingV2 - * - afbBindingV2data + * - @ref afbBindingV2 + * - @ref afbBindingV2data + */ + +/** + * @deprecated use bindings version 3 * + * The global mandatory description of the binding */ #if !defined(AFB_BINDING_MAIN_NAME_V2) extern const struct afb_binding_v2 afbBindingV2; #endif -#if !defined(AFB_BINDING_DATA_NAME_V2) -#define AFB_BINDING_DATA_NAME_V2 afbBindingV2data -#endif - +/** + * @deprecated use bindings version 3 + * + * The global auto declared internal data of the binding + */ #if AFB_BINDING_VERSION != 2 extern #endif -struct afb_binding_data_v2 AFB_BINDING_DATA_NAME_V2 __attribute__ ((weak)); +struct afb_binding_data_v2 afbBindingV2data __attribute__ ((weak)); -#define afb_get_verbosity_v2() (AFB_BINDING_DATA_NAME_V2.verbosity) -#define afb_get_daemon_v2() (AFB_BINDING_DATA_NAME_V2.daemon) -#define afb_get_service_v2() (AFB_BINDING_DATA_NAME_V2.service) +#define afb_get_verbosity_v2() (afbBindingV2data.verbosity) +#define afb_get_daemon_v2() (afbBindingV2data.daemon) +#define afb_get_service_v2() (afbBindingV2data.service) +/******************************************************************************/ /* * Macros for logging messages */ #if defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DATA) -# define _AFB_LOGGING_V2_(vlevel,llevel,...) \ - do{ \ - if(AFB_BINDING_DATA_NAME_V2.verbosity>=vlevel) {\ - if (llevel <= AFB_VERBOSITY_LEVEL_ERROR) \ - afb_daemon_verbose_v2(llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ - else \ - afb_daemon_verbose_v2(llevel,__FILE__,__LINE__,NULL,NULL); \ - } \ - }while(0) -# define _AFB_REQ_LOGGING_V2_(vlevel,llevel,req,...) \ - do{ \ - if(AFB_BINDING_DATA_NAME_V2.verbosity>=vlevel) \ - afb_req_verbose(req,llevel,__FILE__,__LINE__,NULL,NULL); \ - }while(0) +#define AFB_VERBOSE_V2(level,...) \ + do { if(level <= AFB_VERBOSITY_LEVEL_ERROR) \ + afb_daemon_verbose_v2(level,__FILE__,__LINE__,NULL,__VA_ARGS__); \ + else afb_daemon_verbose_v2(level,__FILE__,__LINE__,NULL); } while(0) + +#define AFB_REQ_VERBOSE_V2(req,level,...) \ + do { if(level <= AFB_VERBOSITY_LEVEL_ERROR) \ + afb_req_x1_verbose(req,level,__FILE__,__LINE__,NULL,__VA_ARGS__); \ + else afb_req_x1_verbose(req,level,__FILE__,__LINE__,NULL); } while(0) #elif defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DETAILS) -# define _AFB_LOGGING_V2_(vlevel,llevel,...) \ - do{ \ - if(AFB_BINDING_DATA_NAME_V2.verbosity>=vlevel) \ - afb_daemon_verbose_v2(llevel,NULL,0,NULL,__VA_ARGS__); \ - }while(0) -# define _AFB_REQ_LOGGING_V2_(vlevel,llevel,req,...) \ - do{ \ - if(AFB_BINDING_DATA_NAME_V2.verbosity>=vlevel) \ - afb_req_verbose(req,llevel,NULL,0,NULL,__VA_ARGS__); \ - }while(0) +#define AFB_VERBOSE_V2(level,...) \ + afb_daemon_verbose_v2(level,NULL,0,NULL,__VA_ARGS__) + +#define AFB_REQ_VERBOSE_V2(req,level,...) \ + afb_req_x1_verbose(req,level,NULL,0,NULL,__VA_ARGS__) #else -# define _AFB_LOGGING_V2_(vlevel,llevel,...) \ - do{ \ - if(AFB_BINDING_DATA_NAME_V2.verbosity>=vlevel) \ - afb_daemon_verbose_v2(llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ - }while(0) -# define _AFB_REQ_LOGGING_V2_(vlevel,llevel,req,...) \ - do{ \ - if(AFB_BINDING_DATA_NAME_V2.verbosity>=vlevel) \ - afb_req_verbose(req,llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ - }while(0) +#define AFB_VERBOSE_V2(level,...) \ + afb_daemon_verbose_v2(level,__FILE__,__LINE__,__func__,__VA_ARGS__) + +#define AFB_REQ_VERBOSE_V2(req,level,...) \ + afb_req_x1_verbose(req,level,__FILE__,__LINE__,__func__,__VA_ARGS__) #endif -#include "afb-verbosity.h" -#define AFB_ERROR_V2(...) _AFB_LOGGING_V2_(AFB_VERBOSITY_LEVEL_ERROR,_AFB_SYSLOG_LEVEL_ERROR_,__VA_ARGS__) -#define AFB_WARNING_V2(...) _AFB_LOGGING_V2_(AFB_VERBOSITY_LEVEL_WARNING,_AFB_SYSLOG_LEVEL_WARNING_,__VA_ARGS__) -#define AFB_NOTICE_V2(...) _AFB_LOGGING_V2_(AFB_VERBOSITY_LEVEL_NOTICE,_AFB_SYSLOG_LEVEL_NOTICE_,__VA_ARGS__) -#define AFB_INFO_V2(...) _AFB_LOGGING_V2_(AFB_VERBOSITY_LEVEL_INFO,_AFB_SYSLOG_LEVEL_INFO_,__VA_ARGS__) -#define AFB_DEBUG_V2(...) _AFB_LOGGING_V2_(AFB_VERBOSITY_LEVEL_DEBUG,_AFB_SYSLOG_LEVEL_DEBUG_,__VA_ARGS__) -#define AFB_REQ_ERROR_V2(...) _AFB_REQ_LOGGING_V2_(AFB_VERBOSITY_LEVEL_ERROR,_AFB_SYSLOG_LEVEL_ERROR_,__VA_ARGS__) -#define AFB_REQ_WARNING_V2(...) _AFB_REQ_LOGGING_V2_(AFB_VERBOSITY_LEVEL_WARNING,_AFB_SYSLOG_LEVEL_WARNING_,__VA_ARGS__) -#define AFB_REQ_NOTICE_V2(...) _AFB_REQ_LOGGING_V2_(AFB_VERBOSITY_LEVEL_NOTICE,_AFB_SYSLOG_LEVEL_NOTICE_,__VA_ARGS__) -#define AFB_REQ_INFO_V2(...) _AFB_REQ_LOGGING_V2_(AFB_VERBOSITY_LEVEL_INFO,_AFB_SYSLOG_LEVEL_INFO_,__VA_ARGS__) -#define AFB_REQ_DEBUG_V2(...) _AFB_REQ_LOGGING_V2_(AFB_VERBOSITY_LEVEL_DEBUG,_AFB_SYSLOG_LEVEL_DEBUG_,__VA_ARGS__) +#define _AFB_LOGGING_V2_(vlevel,llevel,...) \ + do{ if(afb_get_verbosity_v2()>=vlevel) AFB_VERBOSE_V2(llevel,__VA_ARGS__); } while(0) +#define _AFB_REQ_LOGGING_V2_(vlevel,llevel,req,...) \ + do{ if(afb_get_verbosity_v2()>=vlevel) AFB_REQ_VERBOSE_V2(req,llevel,__VA_ARGS__); } while(0) + +#define AFB_ERROR_V2(...) _AFB_LOGGING_V2_(AFB_VERBOSITY_LEVEL_ERROR,AFB_SYSLOG_LEVEL_ERROR,__VA_ARGS__) +#define AFB_WARNING_V2(...) _AFB_LOGGING_V2_(AFB_VERBOSITY_LEVEL_WARNING,AFB_SYSLOG_LEVEL_WARNING,__VA_ARGS__) +#define AFB_NOTICE_V2(...) _AFB_LOGGING_V2_(AFB_VERBOSITY_LEVEL_NOTICE,AFB_SYSLOG_LEVEL_NOTICE,__VA_ARGS__) +#define AFB_INFO_V2(...) _AFB_LOGGING_V2_(AFB_VERBOSITY_LEVEL_INFO,AFB_SYSLOG_LEVEL_INFO,__VA_ARGS__) +#define AFB_DEBUG_V2(...) _AFB_LOGGING_V2_(AFB_VERBOSITY_LEVEL_DEBUG,AFB_SYSLOG_LEVEL_DEBUG,__VA_ARGS__) +#define AFB_REQ_ERROR_V2(...) _AFB_REQ_LOGGING_V2_(AFB_VERBOSITY_LEVEL_ERROR,AFB_SYSLOG_LEVEL_ERROR,__VA_ARGS__) +#define AFB_REQ_WARNING_V2(...) _AFB_REQ_LOGGING_V2_(AFB_VERBOSITY_LEVEL_WARNING,AFB_SYSLOG_LEVEL_WARNING,__VA_ARGS__) +#define AFB_REQ_NOTICE_V2(...) _AFB_REQ_LOGGING_V2_(AFB_VERBOSITY_LEVEL_NOTICE,AFB_SYSLOG_LEVEL_NOTICE,__VA_ARGS__) +#define AFB_REQ_INFO_V2(...) _AFB_REQ_LOGGING_V2_(AFB_VERBOSITY_LEVEL_INFO,AFB_SYSLOG_LEVEL_INFO,__VA_ARGS__) +#define AFB_REQ_DEBUG_V2(...) _AFB_REQ_LOGGING_V2_(AFB_VERBOSITY_LEVEL_DEBUG,AFB_SYSLOG_LEVEL_DEBUG,__VA_ARGS__) + +/******************************************************************************/ + +#if 0 && AFB_BINDING_VERSION >= 2 + +# define afb_verbose_error() (afb_get_verbosity() >= AFB_VERBOSITY_LEVEL_ERROR) +# define afb_verbose_warning() (afb_get_verbosity() >= AFB_VERBOSITY_LEVEL_WARNING) +# define afb_verbose_notice() (afb_get_verbosity() >= AFB_VERBOSITY_LEVEL_NOTICE) +# define afb_verbose_info() (afb_get_verbosity() >= AFB_VERBOSITY_LEVEL_INFO) +# define afb_verbose_debug() (afb_get_verbosity() >= AFB_VERBOSITY_LEVEL_DEBUG) + +#endif #include "afb-daemon-v2.h" #include "afb-service-v2.h" diff --git a/include/afb/afb-binding-v3.h b/include/afb/afb-binding-v3.h new file mode 100644 index 00000000..ece3f1c4 --- /dev/null +++ b/include/afb/afb-binding-v3.h @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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. + */ + +/**< @file afb/afb-binding-v3.h */ + +#pragma once + +/******************************************************************************/ + +#include "afb-auth.h" +#include "afb-event-x2.h" +#include "afb-req-x2.h" +#include "afb-session-x2.h" +#include "afb-api-x3.h" + +/******************************************************************************/ + +/** + * @page validity-v3 Validity of a binding v3 + * + * A binding V3 MUST have at least two exported symbols of name: + * + * - @ref afbBindingV3root + * - @ref afbBindingV3 and/or @ref afbBindingV3entry + * + * @ref afbBindingV3root is automatically created when **AFB_BINDING_VERSION == 3** + * without programmer action, as a hidden variable linked as *weak*. + * + * The symbols @ref afbBindingV3 and **afbBindingV3entry** are under control + * of the programmer. + * + * The symbol @ref afbBindingV3 if defined is used, as in binding v2, to describe + * an API that will be declared during pre-initialization of bindings. + * + * The symbol @ref afbBindingV3entry if defined will be called during + * pre-initialization. + * + * If @ref afbBindingV3entry and @ref afbBindingV3 are both defined, it is an + * error to fill the field @ref preinit of @ref afbBindingV3. + * + * @see afb_binding_v3 + * @see afbBindingV3root + * @see afbBindingV3entry + * @see afbBindingV3 + */ + +/** + * Description of one verb as provided for binding API version 3 + */ +struct afb_verb_v3 +{ + /** name of the verb, NULL only at end of the array */ + const char *verb; + + /** callback function implementing the verb */ + void (*callback)(struct afb_req_x2 *req); + + /** required authorization, can be NULL */ + const struct afb_auth *auth; + + /** some info about the verb, can be NULL */ + const char *info; + + /**< data for the verb callback */ + void *vcbdata; + + /** authorization and session requirements of the verb */ + uint16_t session; + + /** is the verb glob name */ + uint16_t glob: 1; +}; + +/** + * Description of the bindings of type version 3 + */ +struct afb_binding_v3 +{ + /** api name for the binding, can't be NULL */ + const char *api; + + /** textual specification of the binding, can be NULL */ + const char *specification; + + /** some info about the api, can be NULL */ + const char *info; + + /** array of descriptions of verbs terminated by a NULL name, can be NULL */ + const struct afb_verb_v3 *verbs; + + /** callback at load of the binding */ + int (*preinit)(struct afb_api_x3 *api); + + /** callback for starting the service */ + int (*init)(struct afb_api_x3 *api); + + /** callback for handling events */ + void (*onevent)(struct afb_api_x3 *api, const char *event, struct json_object *object); + + /** userdata for afb_api_x3 */ + void *userdata; + + /** space separated list of provided class(es) */ + const char *provide_class; + + /** space separated list of required class(es) */ + const char *require_class; + + /** space separated list of required API(es) */ + const char *require_api; + + /** avoids concurrent requests to verbs */ + unsigned noconcurrency: 1; +}; + +/** + * Default root binding's api that can be used when no explicit context is + * available. + * + * When @ref afbBindingV3 is defined, this variable records the corresponding + * api handler. Otherwise, it points to an fake handles that allows logging + * and api creation. + * + * @see afbBindingV3entry + * @see afbBindingV3 + * @see @ref validity-v3 + */ +#if AFB_BINDING_VERSION != 3 +extern +#endif +struct afb_api_x3 *afbBindingV3root __attribute__((weak)); + +/** + * Pre-initialization function. + * + * If this function is defined and exported in the produced binding + * (shared object), it will be called during pre-initialization with the + * rootapi defined by \ref afbBindingV3root + * + * @param rootapi the root api (equals to afbBindingV3root) + * + * @return the function must return a negative integer on error to abort the + * initialization of the binding. Any positive or zero returned value is a + * interpreted as a success. + + * @see afbBindingV3root + * @see afbBindingV3 + * @see @ref validity-v3 + */ +extern int afbBindingV3entry(struct afb_api_x3 *rootapi); + +/** + * Static definition of the root api of the binding. + * + * This symbol if defined describes the API of the binding. + * + * If it is not defined then the function @ref afbBindingV3entry must be defined + * + * @see afbBindingV3root + * @see afbBindingV3entry + * @see @ref validity-v3 + */ +extern const struct afb_binding_v3 afbBindingV3; + +#include "afb-auth.h" +#include "afb-session-x2.h" +#include "afb-verbosity.h" + +#include "afb-event-x2.h" +#include "afb-req-x2.h" +#include "afb-api-x3.h" + +/* + * Macros for logging messages + */ + +#if defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DATA) + +# define AFB_API_VERBOSE_V3(api,level,...) \ + do { if(level <= AFB_VERBOSITY_LEVEL_ERROR) \ + afb_api_v3_verbose(api,level,__FILE__,__LINE__,NULL,__VA_ARGS__); \ + else afb_api_v3_verbose(api,level,__FILE__,__LINE__,NULL); } while(0) + +# define AFB_REQ_VERBOSE_V3(req,level,...) \ + do { if(level <= AFB_VERBOSITY_LEVEL_ERROR) \ + afb_req_x2_verbose(req,level,__FILE__,__LINE__,NULL,__VA_ARGS__); \ + else afb_req_x2_verbose(req,level,__FILE__,__LINE__,NULL); } while(0) + +#elif defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DETAILS) + +# define AFB_API_VERBOSE_V3(api,level,...) \ + afb_api_v3_verbose(api,level,NULL,0,NULL,__VA_ARGS__) + +# define AFB_REQ_VERBOSE_V3(req,level,...) \ + afb_req_x2_verbose(req,level,NULL,0,NULL,__VA_ARGS__) + +#else + +# define AFB_API_VERBOSE_V3(api,level,...) \ + afb_api_x3_verbose(api,level,__FILE__,__LINE__,__func__,__VA_ARGS__) + +# define AFB_REQ_VERBOSE_V3(req,level,...) \ + afb_req_x2_verbose(req,level,__FILE__,__LINE__,__func__,__VA_ARGS__) + +#endif + +#define _AFB_API_LOGGING_V3_(api,llevel,...) \ + do{ if(AFB_SYSLOG_MASK_WANT((api)->logmask,(llevel))) AFB_API_VERBOSE_V3((api),(llevel),__VA_ARGS__); }while(0) +#define _AFB_REQ_LOGGING_V3_(req,llevel,...) \ + do{ if(AFB_SYSLOG_MASK_WANT((req)->api->logmask,(llevel))) AFB_REQ_VERBOSE_V3((req),(llevel),__VA_ARGS__); }while(0) + +#define AFB_API_ERROR_V3(api,...) _AFB_API_LOGGING_V3_(api,AFB_SYSLOG_LEVEL_ERROR,__VA_ARGS__) +#define AFB_API_WARNING_V3(api,...) _AFB_API_LOGGING_V3_(api,AFB_SYSLOG_LEVEL_WARNING,__VA_ARGS__) +#define AFB_API_NOTICE_V3(api,...) _AFB_API_LOGGING_V3_(api,AFB_SYSLOG_LEVEL_NOTICE,__VA_ARGS__) +#define AFB_API_INFO_V3(api,...) _AFB_API_LOGGING_V3_(api,AFB_SYSLOG_LEVEL_INFO,__VA_ARGS__) +#define AFB_API_DEBUG_V3(api,...) _AFB_API_LOGGING_V3_(api,AFB_SYSLOG_LEVEL_DEBUG,__VA_ARGS__) + +#define AFB_REQ_ERROR_V3(req,...) _AFB_REQ_LOGGING_V3_(req,AFB_SYSLOG_LEVEL_ERROR,__VA_ARGS__) +#define AFB_REQ_WARNING_V3(req,...) _AFB_REQ_LOGGING_V3_(req,AFB_SYSLOG_LEVEL_WARNING,__VA_ARGS__) +#define AFB_REQ_NOTICE_V3(req,...) _AFB_REQ_LOGGING_V3_(req,AFB_SYSLOG_LEVEL_NOTICE,__VA_ARGS__) +#define AFB_REQ_INFO_V3(req,...) _AFB_REQ_LOGGING_V3_(req,AFB_SYSLOG_LEVEL_INFO,__VA_ARGS__) +#define AFB_REQ_DEBUG_V3(req,...) _AFB_REQ_LOGGING_V3_(req,AFB_SYSLOG_LEVEL_DEBUG,__VA_ARGS__) + +#define AFB_ERROR_V3(...) AFB_API_ERROR_V3(afbBindingV3root,__VA_ARGS__) +#define AFB_WARNING_V3(...) AFB_API_WARNING_V3(afbBindingV3root,__VA_ARGS__) +#define AFB_NOTICE_V3(...) AFB_API_NOTICE_V3(afbBindingV3root,__VA_ARGS__) +#define AFB_INFO_V3(...) AFB_API_INFO_V3(afbBindingV3root,__VA_ARGS__) +#define AFB_DEBUG_V3(...) AFB_API_DEBUG_V3(afbBindingV3root,__VA_ARGS__) + +#define afb_get_root_api_v3() (afbBindingV3root) +#define afb_get_logmask_v3() (afbBindingV3root->logmask) +#define afb_get_verbosity_v3() AFB_SYSLOG_LEVEL_TO_VERBOSITY(_afb_verbomask_to_upper_level_(afbBindingV3root->logmask)) + +#define afb_daemon_get_event_loop_v3(...) afb_api_get_event_loop(afbBindingV3root,__VA_ARGS__) +#define afb_daemon_get_user_bus_v3(...) afb_api_get_user_bus(afbBindingV3root,__VA_ARGS__) +#define afb_daemon_get_system_bus_v3(...) afb_api_get_system_bus(afbBindingV3root,__VA_ARGS__) +#define afb_daemon_broadcast_event_v3(...) afb_api_broadcast_event(afbBindingV3root,__VA_ARGS__) +#define afb_daemon_make_event_v3(...) afb_api_make_event(afbBindingV3root,__VA_ARGS__) +#define afb_daemon_verbose_v3(...) afb_api_verbose(afbBindingV3root,__VA_ARGS__) +#define afb_daemon_rootdir_get_fd_v3() afb_api_rootdir_get_fd(afbBindingV3root) +#define afb_daemon_rootdir_open_locale_v3(...) afb_api_rootdir_open_locale(afbBindingV3root,__VA_ARGS__) +#define afb_daemon_queue_job_v3(...) afb_api_queue_job(afbBindingV3root,__VA_ARGS__) +#define afb_daemon_require_api_v3(...) afb_api_require_api(afbBindingV3root,__VA_ARGS__) +#define afb_daemon_add_alias_v3(...) afb_api_add_alias(afbBindingV3root,__VA_ARGS__) + +#define afb_service_call_v3(...) afb_api_call_legacy(afbBindingV3root,__VA_ARGS__) +#define afb_service_call_sync_v3(...) afb_api_call_sync_legacy(afbBindingV3root,__VA_ARGS__) + diff --git a/include/afb/afb-binding-vdyn.h b/include/afb/afb-binding-vdyn.h deleted file mode 100644 index 357a85f6..00000000 --- a/include/afb/afb-binding-vdyn.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2016, 2017, 2018 "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 "afb-auth.h" -#include "afb-session-v2.h" -#include "afb-verbosity.h" - -#include "afb-eventid.h" -#include "afb-request.h" -#include "afb-dynapi.h" - -/* - * The function afbBindingVdyn if exported allows to create - * pure dynamic bindings. When the binding is loaded, it receives - * a virtual dynapi that can be used to create apis. The - * given API can not be used except for creating dynamic apis. - */ -extern int afbBindingVdyn(struct afb_dynapi *dynapi); - -/* - * Macros for logging messages - */ -#if defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DATA) - -# define _AFB_DYNAPI_LOGGING_(vlevel,llevel,dynapi,...) \ - do{ \ - if(dynapi->verbosity>=vlevel) {\ - if (llevel <= AFB_VERBOSITY_LEVEL_ERROR) \ - afb_dynapi_verbose(dynapi,llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ - else \ - afb_dynapi_verbose(dynapi,llevel,__FILE__,__LINE__,NULL,NULL); \ - } \ - }while(0) -# define _AFB_REQUEST_LOGGING_(vlevel,llevel,request,...) \ - do{ \ - if(request->dynapi->verbosity>=vlevel) \ - afb_request_verbose(request,llevel,__FILE__,__LINE__,NULL,NULL); \ - }while(0) - -#elif defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DETAILS) - -# define _AFB_DYNAPI_LOGGING_(vlevel,llevel,dynapi,...) \ - do{ \ - if(dynapi->verbosity>=vlevel) \ - afb_dynapi_verbose(dynapi,llevel,NULL,0,NULL,__VA_ARGS__); \ - }while(0) -# define _AFB_REQUEST_LOGGING_(vlevel,llevel,request,...) \ - do{ \ - if(request->dynapi->verbosity>=vlevel) \ - afb_request_verbose(request,llevel,NULL,0,NULL,__VA_ARGS__); \ - }while(0) - -#else - -# define _AFB_DYNAPI_LOGGING_(vlevel,llevel,dynapi,...) \ - do{ \ - if(dynapi->verbosity>=vlevel) \ - afb_dynapi_verbose(dynapi,llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ - }while(0) -# define _AFB_REQUEST_LOGGING_(vlevel,llevel,request,...) \ - do{ \ - if(request->dynapi->verbosity>=vlevel) \ - afb_request_verbose(request,llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ - }while(0) - -#endif - -#define AFB_DYNAPI_ERROR(...) _AFB_DYNAPI_LOGGING_(AFB_VERBOSITY_LEVEL_ERROR,_AFB_SYSLOG_LEVEL_ERROR_,__VA_ARGS__) -#define AFB_DYNAPI_WARNING(...) _AFB_DYNAPI_LOGGING_(AFB_VERBOSITY_LEVEL_WARNING,_AFB_SYSLOG_LEVEL_WARNING_,__VA_ARGS__) -#define AFB_DYNAPI_NOTICE(...) _AFB_DYNAPI_LOGGING_(AFB_VERBOSITY_LEVEL_NOTICE,_AFB_SYSLOG_LEVEL_NOTICE_,__VA_ARGS__) -#define AFB_DYNAPI_INFO(...) _AFB_DYNAPI_LOGGING_(AFB_VERBOSITY_LEVEL_INFO,_AFB_SYSLOG_LEVEL_INFO_,__VA_ARGS__) -#define AFB_DYNAPI_DEBUG(...) _AFB_DYNAPI_LOGGING_(AFB_VERBOSITY_LEVEL_DEBUG,_AFB_SYSLOG_LEVEL_DEBUG_,__VA_ARGS__) -#define AFB_REQUEST_ERROR(...) _AFB_REQUEST_LOGGING_(AFB_VERBOSITY_LEVEL_ERROR,_AFB_SYSLOG_LEVEL_ERROR_,__VA_ARGS__) -#define AFB_REQUEST_WARNING(...) _AFB_REQUEST_LOGGING_(AFB_VERBOSITY_LEVEL_WARNING,_AFB_SYSLOG_LEVEL_WARNING_,__VA_ARGS__) -#define AFB_REQUEST_NOTICE(...) _AFB_REQUEST_LOGGING_(AFB_VERBOSITY_LEVEL_NOTICE,_AFB_SYSLOG_LEVEL_NOTICE_,__VA_ARGS__) -#define AFB_REQUEST_INFO(...) _AFB_REQUEST_LOGGING_(AFB_VERBOSITY_LEVEL_INFO,_AFB_SYSLOG_LEVEL_INFO_,__VA_ARGS__) -#define AFB_REQUEST_DEBUG(...) _AFB_REQUEST_LOGGING_(AFB_VERBOSITY_LEVEL_DEBUG,_AFB_SYSLOG_LEVEL_DEBUG_,__VA_ARGS__) - - diff --git a/include/afb/afb-binding.h b/include/afb/afb-binding.h index 37305991..085dc388 100644 --- a/include/afb/afb-binding.h +++ b/include/afb/afb-binding.h @@ -17,246 +17,105 @@ #pragma once +/** + * @mainpage + * + * @section brief Brief introduction + * + * This is part of the AGL framework micro-service binder and is provided as the + * API for writing bindings. + * + * The normal usage is to include only one file as below: + * + * ```C + * #define AFB_BINDING_VERSION 3 + * #include <afb/afb-binding.h> + * ``` + * + * @example tuto-1.c + * @example tuto-2.c + */ +/** + * @file afb/afb-binding.h + */ + #include <stdarg.h> +#include <stdint.h> +struct json_object; -/***************************************************************************** - * This files is the main file to include for writing bindings dedicated to +/** + * @def AFB_BINDING_INTERFACE_VERSION + + * * Version of the binding interface. * - * AFB-DAEMON + * This is intended to be test for tuning condition code. + * It is of the form MAJOR * 1000 + REVISION. * - * Functions of bindings of afb-daemon are accessible by authorized clients - * through the apis module of afb-daemon. + * @see AFB_BINDING_UPPER_VERSION that should match MAJOR */ +#define AFB_BINDING_INTERFACE_VERSION 3000 +/** + * @def AFB_BINDING_LOWER_VERSION + * + * Lowest binding API version supported. + * + * @see AFB_BINDING_VERSION + * @see AFB_BINDING_UPPER_VERSION + */ #define AFB_BINDING_LOWER_VERSION 1 -#define AFB_BINDING_UPPER_VERSION 2 + +/** + * @def AFB_BINDING_UPPER_VERSION + * + * Upper binding API version supported. + * + * @see AFB_BINDING_VERSION + * @see AFB_BINDING_LOWER_VERSION + */ +#define AFB_BINDING_UPPER_VERSION 3 + +/** + * @def AFB_BINDING_VERSION + * + * This macro must be defined before including <afb/afb-binding.h> to set + * the required binding API. + */ #ifndef AFB_BINDING_VERSION -#define AFB_BINDING_VERSION 1 -#pragma GCC warning "\ +#error "\ \n\ \n\ AFB_BINDING_VERSION should be defined before including <afb/afb-binding.h>\n\ AFB_BINDING_VERSION defines the version of binding that you use.\n\ - Currently, known versions are 1 or 2.\n\ - Setting now AFB_BINDING_VERSION to 1 (version 1 by default)\n\ - NOTE THAT VERSION 2 IS NOW RECOMMENDED!\n\ + Currently the version to use is 3 (older versions: 1 is obsolete, 2 is legacy).\n\ Consider to add one of the following define before including <afb/afb-binding.h>:\n\ \n\ - #define AFB_BINDING_VERSION 1\n\ - #define AFB_BINDING_VERSION 2\n\ + #define AFB_BINDING_VERSION 3\n\ \n\ - Note that in some case it will enforce you to include <stdio.h>\n\ " -#include <stdio.h> /* old version side effect */ #else # if AFB_BINDING_VERSION == 1 -# pragma GCC warning "Using binding version 1, consider to switch to version 2" +# pragma GCC warning "Using binding version 1, consider to switch to version 3" +# endif +# if AFB_BINDING_VERSION == 2 +# pragma GCC warning "Using binding version 2, consider to switch to version 3" # endif #endif #if AFB_BINDING_VERSION != 0 # if AFB_BINDING_VERSION < AFB_BINDING_LOWER_VERSION || AFB_BINDING_VERSION > AFB_BINDING_UPPER_VERSION -# error "Unsupported binding version AFB_BINDING_VERSION " #AFB_BINDING_VERSION +# error "Unsupported binding version AFB_BINDING_VERSION" # endif #endif -/* - * Some function of the library are exported to afb-daemon. - */ - +/***************************************************************************************************/ +#include "afb-binding-predefs.h" #include "afb-binding-v1.h" #include "afb-binding-v2.h" -#include "afb-binding-vdyn.h" - -typedef struct afb_verb_desc_v1 afb_verb_desc_v1; -typedef struct afb_binding_desc_v1 afb_binding_desc_v1; -typedef struct afb_binding_v1 afb_binding_v1; -typedef struct afb_binding_interface_v1 afb_binding_interface_v1; - -typedef struct afb_verb_v2 afb_verb_v2; -typedef struct afb_binding_v2 afb_binding_v2; - -typedef enum afb_auth_type afb_auth_type; -typedef struct afb_auth afb_auth; -typedef struct afb_daemon afb_daemon; -typedef struct afb_event afb_event; -typedef struct afb_arg afb_arg; -typedef struct afb_req afb_req; -typedef struct afb_stored_req afb_stored_req; -typedef struct afb_service afb_service; - -typedef struct afb_dynapi afb_dynapi; -typedef struct afb_request afb_request; -typedef struct afb_eventid afb_eventid; - -#if 0 -/* these typedef's shouldn't be needed */ -typedef enum afb_binding_type_v1 afb_binding_type_v1; -typedef enum afb_mode_v1 afb_mode_v1; -typedef enum afb_session_flags_v1 afb_session_flags_v1; -typedef enum afb_session_flags_v2 afb_session_flags_v2; -typedef struct afb_binding_data_v2 afb_binding_data_v2; -typedef struct afb_daemon_itf afb_daemon_itf; -typedef struct afb_event_itf afb_event_itf; -typedef struct afb_req_itf afb_req_itf; -typedef struct afb_service_itf afb_service_itf; -#endif - -/***************************************************************************************************/ - -#if AFB_BINDING_VERSION == 1 - -# define afb_binding afb_binding_v1 -# define afb_binding_interface afb_binding_interface_v1 - -# define AFB_SESSION_NONE AFB_SESSION_NONE_V1 -# define AFB_SESSION_CREATE AFB_SESSION_CREATE_V1 -# define AFB_SESSION_CLOSE AFB_SESSION_CLOSE_V1 -# define AFB_SESSION_RENEW AFB_SESSION_RENEW_V1 -# define AFB_SESSION_CHECK AFB_SESSION_CHECK_V1 - -# define AFB_SESSION_LOA_GE AFB_SESSION_LOA_GE_V1 -# define AFB_SESSION_LOA_LE AFB_SESSION_LOA_LE_V1 -# define AFB_SESSION_LOA_EQ AFB_SESSION_LOA_EQ_V1 - -# define AFB_SESSION_LOA_SHIFT AFB_SESSION_LOA_SHIFT_V1 -# define AFB_SESSION_LOA_MASK AFB_SESSION_LOA_MASK_V1 - -# define AFB_SESSION_LOA_0 AFB_SESSION_LOA_0_V1 -# define AFB_SESSION_LOA_1 AFB_SESSION_LOA_1_V1 -# define AFB_SESSION_LOA_2 AFB_SESSION_LOA_2_V1 -# define AFB_SESSION_LOA_3 AFB_SESSION_LOA_3_V1 -# define AFB_SESSION_LOA_4 AFB_SESSION_LOA_4_V1 - -# define AFB_SESSION_LOA_LE_0 AFB_SESSION_LOA_LE_0_V1 -# define AFB_SESSION_LOA_LE_1 AFB_SESSION_LOA_LE_1_V1 -# define AFB_SESSION_LOA_LE_2 AFB_SESSION_LOA_LE_2_V1 -# define AFB_SESSION_LOA_LE_3 AFB_SESSION_LOA_LE_3_V1 - -# define AFB_SESSION_LOA_EQ_0 AFB_SESSION_LOA_EQ_0_V1 -# define AFB_SESSION_LOA_EQ_1 AFB_SESSION_LOA_EQ_1_V1 -# define AFB_SESSION_LOA_EQ_2 AFB_SESSION_LOA_EQ_2_V1 -# define AFB_SESSION_LOA_EQ_3 AFB_SESSION_LOA_EQ_3_V1 - -# define AFB_SESSION_LOA_GE_0 AFB_SESSION_LOA_GE_0_V1 -# define AFB_SESSION_LOA_GE_1 AFB_SESSION_LOA_GE_1_V1 -# define AFB_SESSION_LOA_GE_2 AFB_SESSION_LOA_GE_2_V1 -# define AFB_SESSION_LOA_GE_3 AFB_SESSION_LOA_GE_3_V1 - -# define AFB_ERROR AFB_ERROR_V1 -# define AFB_WARNING AFB_WARNING_V1 -# define AFB_NOTICE AFB_NOTICE_V1 -# define AFB_INFO AFB_INFO_V1 -# define AFB_DEBUG AFB_DEBUG_V1 - -# define AFB_REQ_ERROR AFB_REQ_ERROR_V1 -# define AFB_REQ_WARNING AFB_REQ_WARNING_V1 -# define AFB_REQ_NOTICE AFB_REQ_NOTICE_V1 -# define AFB_REQ_INFO AFB_REQ_INFO_V1 -# define AFB_REQ_DEBUG AFB_REQ_DEBUG_V1 - -#define afb_daemon_get_event_loop afb_daemon_get_event_loop_v1 -#define afb_daemon_get_user_bus afb_daemon_get_user_bus_v1 -#define afb_daemon_get_system_bus afb_daemon_get_system_bus_v1 -#define afb_daemon_broadcast_event afb_daemon_broadcast_event_v1 -#define afb_daemon_make_event afb_daemon_make_event_v1 -#define afb_daemon_verbose afb_daemon_verbose_v1 -#define afb_daemon_rootdir_get_fd afb_daemon_rootdir_get_fd_v1 -#define afb_daemon_rootdir_open_locale afb_daemon_rootdir_open_locale_v1 -#define afb_daemon_queue_job afb_daemon_queue_job_v1 -#define afb_daemon_require_api afb_daemon_require_api_v1 -#define afb_daemon_rename_api afb_daemon_rename_api_v1 - -#define afb_service_call afb_service_call_v1 -#define afb_service_call_sync afb_service_call_sync_v1 - -#define afb_req_store afb_req_store_v1 -#define afb_req_unstore afb_req_unstore_v1 - -#endif - -/***************************************************************************************************/ - -#if AFB_BINDING_VERSION == 2 - -# define afb_binding afb_binding_v2 -# define afb_get_verbosity afb_get_verbosity_v2 -# define afb_get_daemon afb_get_daemon_v2 -# define afb_get_service afb_get_service_v2 - - -# define AFB_SESSION_NONE AFB_SESSION_NONE_V2 -# define AFB_SESSION_CLOSE AFB_SESSION_CLOSE_V2 -# define AFB_SESSION_RENEW AFB_SESSION_REFRESH_V2 -# define AFB_SESSION_REFRESH AFB_SESSION_REFRESH_V2 -# define AFB_SESSION_CHECK AFB_SESSION_CHECK_V2 - -# define AFB_SESSION_LOA_MASK AFB_SESSION_LOA_MASK_V2 - -# define AFB_SESSION_LOA_0 AFB_SESSION_LOA_0_V2 -# define AFB_SESSION_LOA_1 AFB_SESSION_LOA_1_V2 -# define AFB_SESSION_LOA_2 AFB_SESSION_LOA_2_V2 -# define AFB_SESSION_LOA_3 AFB_SESSION_LOA_3_V2 - -# define AFB_ERROR AFB_ERROR_V2 -# define AFB_WARNING AFB_WARNING_V2 -# define AFB_NOTICE AFB_NOTICE_V2 -# define AFB_INFO AFB_INFO_V2 -# define AFB_DEBUG AFB_DEBUG_V2 - -# define AFB_REQ_ERROR AFB_REQ_ERROR_V2 -# define AFB_REQ_WARNING AFB_REQ_WARNING_V2 -# define AFB_REQ_NOTICE AFB_REQ_NOTICE_V2 -# define AFB_REQ_INFO AFB_REQ_INFO_V2 -# define AFB_REQ_DEBUG AFB_REQ_DEBUG_V2 - -#define afb_daemon_get_event_loop afb_daemon_get_event_loop_v2 -#define afb_daemon_get_user_bus afb_daemon_get_user_bus_v2 -#define afb_daemon_get_system_bus afb_daemon_get_system_bus_v2 -#define afb_daemon_broadcast_event afb_daemon_broadcast_event_v2 -#define afb_daemon_make_event afb_daemon_make_event_v2 -#define afb_daemon_verbose afb_daemon_verbose_v2 -#define afb_daemon_rootdir_get_fd afb_daemon_rootdir_get_fd_v2 -#define afb_daemon_rootdir_open_locale afb_daemon_rootdir_open_locale_v2 -#define afb_daemon_queue_job afb_daemon_queue_job_v2 -#define afb_daemon_unstore_req afb_daemon_unstore_req_v2 -#define afb_daemon_require_api afb_daemon_require_api_v2 -#define afb_daemon_rename_api afb_daemon_rename_api_v2 - -#define afb_service_call afb_service_call_v2 -#define afb_service_call_sync afb_service_call_sync_v2 - -#define afb_req_store afb_req_store_v2 -#define afb_req_unstore afb_daemon_unstore_req_v2 - -#endif - -/***************************************************************************************************/ - -#if AFB_BINDING_VERSION >= 2 - -# define afb_verbose_error() (afb_get_verbosity() >= AFB_VERBOSITY_LEVEL_ERROR) -# define afb_verbose_warning() (afb_get_verbosity() >= AFB_VERBOSITY_LEVEL_WARNING) -# define afb_verbose_notice() (afb_get_verbosity() >= AFB_VERBOSITY_LEVEL_NOTICE) -# define afb_verbose_info() (afb_get_verbosity() >= AFB_VERBOSITY_LEVEL_INFO) -# define afb_verbose_debug() (afb_get_verbosity() >= AFB_VERBOSITY_LEVEL_DEBUG) - -#endif - -/***************************************************************************************************/ - -#if defined(AFB_BINDING_PRAGMA_KEEP_VERBOSE_UNPREFIX) -# define ERROR AFB_ERROR -# define WARNING AFB_WARNING -# define NOTICE AFB_NOTICE -# define INFO AFB_INFO -# define DEBUG AFB_DEBUG - -# define REQ_ERROR AFB_REQ_ERROR -# define REQ_WARNING AFB_REQ_WARNING -# define REQ_NOTICE AFB_REQ_NOTICE -# define REQ_INFO AFB_REQ_INFO -# define REQ_DEBUG AFB_REQ_DEBUG +#include "afb-binding-v3.h" +#if defined(AFB_BINDING_WANT_DYNAPI) +# include "afb-dynapi-legacy.h" #endif +#include "afb-binding-postdefs.h" diff --git a/include/afb/afb-binding.hpp b/include/afb/afb-binding.hpp index ee151339..27715f39 100644 --- a/include/afb/afb-binding.hpp +++ b/include/afb/afb-binding.hpp @@ -17,18 +17,19 @@ #pragma once +#include <cstddef> #include <cstdlib> #include <cstdarg> #include <functional> /* ensure version */ #ifndef AFB_BINDING_VERSION -# define AFB_BINDING_VERSION 2 +# define AFB_BINDING_VERSION 3 #endif /* check the version */ #if AFB_BINDING_VERSION < 2 -# error "AFB_BINDING_VERSION must be at least 2" +# error "AFB_BINDING_VERSION must be at least 2 but 3 is prefered" #endif /* get C definitions of bindings */ @@ -44,16 +45,11 @@ namespace afb { class arg; class event; class req; -class stored_req; /*************************************************************************/ /* declaration of functions */ /*************************************************************************/ -struct sd_event *get_event_loop(); -struct sd_bus *get_system_bus(); -struct sd_bus *get_user_bus(); - int broadcast_event(const char *name, json_object *object = nullptr); event make_event(const char *name); @@ -70,7 +66,7 @@ int queue_job(void (*callback)(int signum, void *arg), void *argument, void *gro int require_api(const char *apiname, bool initialized = true); -int rename_api(const char *apiname); +int add_alias(const char *apiname, const char *aliasname); int verbosity(); @@ -80,9 +76,17 @@ bool wants_notices(); bool wants_infos(); bool wants_debugs(); +#if AFB_BINDING_VERSION >= 3 +void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result, afb_api_t api), void *closure); + +template <class T> void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, int iserror, struct json_object *result, afb_api_t api), T *closure); + +bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result); +#else void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result), void *closure); template <class T> void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, int iserror, struct json_object *result), T *closure); +#endif bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result); @@ -93,14 +97,15 @@ bool callsync(const char *api, const char *verb, struct json_object *args, struc /* events */ class event { - struct afb_event event_; + afb_event_t event_; public: - event() { event_.itf = nullptr; event_.closure = nullptr; } - event(const struct afb_event &e); + event() { invalidate(); } + event(afb_event_t e); event(const event &other); event &operator=(const event &other); - operator const struct afb_event&() const; + operator afb_event_t() const; + afb_event_t operator->() const; operator bool() const; bool is_valid() const; @@ -139,30 +144,16 @@ public: /* req(uest) */ class req { - struct afb_req req_; -public: - class stored - { - struct afb_stored_req *sreq_; - - friend class req; - stored() = delete; - stored(struct afb_stored_req *sr); - public: - stored(const stored &other); - stored &operator =(const stored &other); - req unstore() const; - }; - - class stored; + afb_req_t req_; public: req() = delete; - req(const struct afb_req &r); + req(afb_req_t r); req(const req &other); req &operator=(const req &other); - operator const struct afb_req&() const; + operator afb_req_t() const; + afb_req_t operator->() const; operator bool() const; bool is_valid() const; @@ -175,22 +166,20 @@ public: json_object *json() const; + void reply(json_object *obj = nullptr, const char *error = nullptr, const char *info = nullptr) const; + void replyf(json_object *obj, const char *error, const char *info, ...) const; + void replyv(json_object *obj, const char *error, const char *info, va_list args) const; + void success(json_object *obj = nullptr, const char *info = nullptr) const; void successf(json_object *obj, const char *info, ...) const; + void successv(json_object *obj, const char *info, va_list args) const; - void fail(const char *status = "failed", const char *info = nullptr) const; - void failf(const char *status, const char *info, ...) const; - - void *context_get() const; - - void context_set(void *context, void (*free_context)(void*)) const; - - void *context(void *(*create_context)(), void (*free_context)(void*)) const; + void fail(const char *error = "failed", const char *info = nullptr) const; + void failf(const char *error, const char *info, ...) const; + void failv(const char *error, const char *info, va_list args) const; template < class T > T *context() const; - void context_clear() const; - void addref() const; void unref() const; @@ -199,19 +188,22 @@ public: bool session_set_LOA(unsigned level) const; - stored store() const; - bool subscribe(const event &event) const; bool unsubscribe(const event &event) const; - void subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result), void *closure) const; + void subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, afb_req_t req), void *closure) const; + template <class T> void subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result, afb_req_t req), T *closure) const; - void subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, afb_req req), void *closure) const; + bool subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const; - template <class T> void subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result), T *closure) const; +#if AFB_BINDING_VERSION >= 3 + void subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(void *closure, json_object *object, const char *error, const char *info, afb_req_t req), void *closure) const; - bool subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const; + template <class T> void subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(T *closure, json_object *object, const char *error, const char *info, afb_req_t req), T *closure) const; + + bool subcallsync(const char *api, const char *verb, json_object *args, int flags, struct json_object *&object, char *&error, char *&info) const; +#endif void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const; @@ -222,6 +214,8 @@ public: char *get_application_id() const; int get_uid() const; + + json_object *get_client_info() const; }; /*************************************************************************/ @@ -250,18 +244,23 @@ public: /*************************************************************************/ /* events */ -inline event::event(const struct afb_event &e) : event_(e) { } +inline event::event(afb_event_t e) : event_(e) { } inline event::event(const event &other) : event_(other.event_) { } inline event &event::operator=(const event &other) { event_ = other.event_; return *this; } -inline event::operator const struct afb_event&() const { return event_; } +inline event::operator afb_event_t() const { return event_; } +inline afb_event_t event::operator->() const { return event_; } inline event::operator bool() const { return is_valid(); } -inline bool event::is_valid() const { return afb_event_is_valid(event_); } +inline bool event::is_valid() const { return afb_event_is_valid(event_); } -inline void event::invalidate() { event_.itf = NULL; event_.closure = NULL; } +#if AFB_BINDING_VERSION >= 3 +inline void event::invalidate() { event_ = nullptr; } +#else +inline void event::invalidate() { event_ = { nullptr, nullptr }; } +#endif -inline int event::broadcast(json_object *object) const { return afb_event_broadcast(event_, object); } +inline int event::broadcast(json_object *object) const { return afb_event_broadcast(event_, object); } inline int event::push(json_object *object) const { return afb_event_push(event_, object); } inline void event::unref() { afb_event_unref(event_); invalidate(); } @@ -285,23 +284,16 @@ inline const char *arg::path() const { return arg_.path; } /* req(uests)s */ -inline req::stored::stored(struct afb_stored_req *sr) : sreq_(sr) {} - -inline req::stored::stored(const req::stored &other) : sreq_(other.sreq_) {} - -inline req::stored &req::stored::operator =(const req::stored &other) { sreq_ = other.sreq_; return *this; } - -inline req req::stored::unstore() const { return req(afb_daemon_unstore_req_v2(sreq_)); } - -inline req::req(const struct afb_req &r) : req_(r) {} +inline req::req(afb_req_t r) : req_(r) {} inline req::req(const req &other) : req_(other.req_) {} inline req &req::operator=(const req &other) { req_ = other.req_; return *this; } -inline req::operator const struct afb_req&() const { return req_; } +inline req::operator afb_req_t() const { return req_; } +inline afb_req_t req::operator->() const { return req_; } -inline req::operator bool() const { return !!afb_req_is_valid(req_); } -inline bool req::is_valid() const { return !!afb_req_is_valid(req_); } +inline req::operator bool() const { return is_valid(); } +inline bool req::is_valid() const { return afb_req_is_valid(req_); } inline arg req::get(const char *name) const { return arg(afb_req_get(req_, name)); } @@ -311,160 +303,210 @@ inline const char *req::path(const char *name) const { return afb_req_path(req_, inline json_object *req::json() const { return afb_req_json(req_); } -inline void req::success(json_object *obj, const char *info) const { afb_req_success(req_, obj, info); } -inline void req::successf(json_object *obj, const char *info, ...) const +inline void req::reply(json_object *obj, const char *error, const char *info) const { afb_req_reply(req_, obj, error, info); } +inline void req::replyv(json_object *obj, const char *error, const char *info, va_list args) const { afb_req_reply_v(req_, obj, error, info, args); } +inline void req::replyf(json_object *obj, const char *error, const char *info, ...) const { va_list args; va_start(args, info); - afb_req_success_v(req_, obj, info, args); + replyv(obj, error, info, args); va_end(args); } -inline void req::fail(const char *status, const char *info) const { afb_req_fail(req_, status, info); } -inline void req::failf(const char *status, const char *info, ...) const +inline void req::success(json_object *obj, const char *info) const { reply(obj, nullptr, info); } +inline void req::successv(json_object *obj, const char *info, va_list args) const { replyv(obj, nullptr, info, args); } +inline void req::successf(json_object *obj, const char *info, ...) const { va_list args; va_start(args, info); - afb_req_fail_v(req_, status, info, args); + successv(obj, info, args); va_end(args); } -inline void *req::context_get() const { return afb_req_context_get(req_); } - -inline void req::context_set(void *context, void (*free_context)(void*)) const { afb_req_context_set(req_, context, free_context); } - -inline void *req::context(void *(*create_context)(), void (*free_context)(void*)) const { return afb_req_context(req_, create_context, free_context); } +inline void req::fail(const char *error, const char *info) const { reply(nullptr, error, info); } +inline void req::failv(const char *error, const char *info, va_list args) const { replyv(nullptr, error, info, args); } +inline void req::failf(const char *error, const char *info, ...) const +{ + va_list args; + va_start(args, info); + failv(error, info, args); + va_end(args); +} template < class T > inline T *req::context() const { +#if AFB_BINDING_VERSION >= 3 + T* (*creater)(void*) = [](){return new T();}; + void (*freer)(T*) = [](T*t){delete t;}; + return reinterpret_cast<T*>(afb_req_context(req_, 0, + reinterpret_cast<void *(*)(void*)>(creater), + reinterpret_cast<void (*)(void*)>(freer), nullptr)); +#else T* (*creater)() = [](){return new T();}; void (*freer)(T*) = [](T*t){delete t;}; return reinterpret_cast<T*>(afb_req_context(req_, reinterpret_cast<void *(*)()>(creater), reinterpret_cast<void (*)(void*)>(freer))); +#endif } -inline void req::context_clear() const { afb_req_context_clear(req_); } - inline void req::addref() const { afb_req_addref(req_); } inline void req::unref() const { afb_req_unref(req_); } inline void req::session_close() const { afb_req_session_close(req_); } -inline bool req::session_set_LOA(unsigned level) const { return !!afb_req_session_set_LOA(req_, level); } - -inline req::stored req::store() const { return stored(afb_req_store_v2(req_)); } +inline bool req::session_set_LOA(unsigned level) const { return !afb_req_session_set_LOA(req_, level); } inline bool req::subscribe(const event &event) const { return !afb_req_subscribe(req_, event); } inline bool req::unsubscribe(const event &event) const { return !afb_req_unsubscribe(req_, event); } -inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result), void *closure) const + + + + +#if AFB_BINDING_VERSION >= 3 + +inline void req::subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(void *closure, json_object *result, const char *error, const char *info, afb_req_t req), void *closure) const { - afb_req_subcall(req_, api, verb, args, callback, closure); + afb_req_subcall(req_, api, verb, args, flags, callback, closure); } -inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, struct afb_req req), void *closure) const +template <class T> +inline void req::subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(T *closure, json_object *result, const char *error, const char *info, afb_req_t req), T *closure) const { + subcall(api, verb, args, flags, reinterpret_cast<void(*)(void*,json_object*,const char*,const char*,afb_req_t)>(callback), reinterpret_cast<void*>(closure)); +} + +inline bool req::subcallsync(const char *api, const char *verb, json_object *args, int flags, struct json_object *&object, char *&error, char *&info) const +{ + return !afb_req_subcall_sync(req_, api, verb, args, flags, &object, &error, &info); +} + +#endif + +inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, afb_req_t req), void *closure) const +{ +#if AFB_BINDING_VERSION >= 3 + afb_req_subcall_legacy(req_, api, verb, args, callback, closure); +#else afb_req_subcall_req(req_, api, verb, args, callback, closure); +#endif } template <class T> -inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result), T *closure) const +inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result, afb_req_t req), T *closure) const { - afb_req_subcall(req_, api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*)>(callback), reinterpret_cast<void*>(closure)); + subcall(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*,afb_req_t)>(callback), reinterpret_cast<void*>(closure)); } inline bool req::subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const { - return !!afb_req_subcall_sync(req_, api, verb, args, &result); +#if AFB_BINDING_VERSION >= 3 + return !afb_req_subcall_sync_legacy(req_, api, verb, args, &result); +#else + return !afb_req_subcall_sync(req_, api, verb, args, &result); +#endif } inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const { - req_.itf->vverbose(req_.closure, level, file, line, func, fmt, args); + afb_req_verbose(req_, level, file, line, func, fmt, args); } inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const { va_list args; va_start(args, fmt); - req_.itf->vverbose(req_.closure, level, file, line, func, fmt, args); + afb_req_verbose(req_, level, file, line, func, fmt, args); va_end(args); } inline bool req::has_permission(const char *permission) const { - return bool(req_.itf->has_permission(req_.closure, permission)); + return bool(afb_req_has_permission(req_, permission)); } inline char *req::get_application_id() const { - return req_.itf->get_application_id(req_.closure); + return afb_req_get_application_id(req_); } inline int req::get_uid() const { - return req_.itf->get_uid(req_.closure); + return afb_req_get_uid(req_); } -/* commons */ -inline struct sd_event *get_event_loop() - { return afb_daemon_get_event_loop_v2(); } - -inline struct sd_bus *get_system_bus() - { return afb_daemon_get_system_bus_v2(); } - -inline struct sd_bus *get_user_bus() - { return afb_daemon_get_user_bus_v2(); } +inline json_object *req::get_client_info() const +{ + return afb_req_get_client_info(req_); +} +/* commons */ inline int broadcast_event(const char *name, json_object *object) - { return afb_daemon_broadcast_event_v2(name, object); } + { return afb_daemon_broadcast_event(name, object); } inline event make_event(const char *name) - { return afb_daemon_make_event_v2(name); } + { return afb_daemon_make_event(name); } inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) - { afb_daemon_verbose_v2(level, file, line, func, fmt, args); } + { afb_daemon_verbose(level, file, line, func, fmt, args); } inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) { va_list args; va_start(args, fmt); verbose(level, file, line, func, fmt, args); va_end(args); } inline int rootdir_get_fd() - { return afb_daemon_rootdir_get_fd_v2(); } + { return afb_daemon_rootdir_get_fd(); } inline int rootdir_open_locale_fd(const char *filename, int flags, const char *locale) - { return afb_daemon_rootdir_open_locale_v2(filename, flags, locale); } + { return afb_daemon_rootdir_open_locale(filename, flags, locale); } inline int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout) - { return afb_daemon_queue_job_v2(callback, argument, group, timeout); } + { return afb_daemon_queue_job(callback, argument, group, timeout); } inline int require_api(const char *apiname, bool initialized) - { return afb_daemon_require_api_v2(apiname, int(initialized)); } + { return afb_daemon_require_api(apiname, int(initialized)); } -inline int rename_api(const char *apiname) - { return afb_daemon_rename_api_v2(apiname); } +inline int add_alias(const char *apiname, const char *aliasname) + { return afb_daemon_add_alias(apiname, aliasname); } -inline int verbosity() - { return afb_get_verbosity(); } +#if AFB_BINDING_VERSION >= 3 +inline int logmask() + { return afb_get_logmask(); } +#else +inline int logmask() + { return (1 << (1 + afb_get_verbosity() + AFB_SYSLOG_LEVEL_ERROR)) - 1; } +#endif inline bool wants_errors() - { return afb_verbose_error(); } + { return AFB_SYSLOG_MASK_WANT_ERROR(logmask()); } inline bool wants_warnings() - { return afb_verbose_warning(); } + { return AFB_SYSLOG_MASK_WANT_WARNING(logmask()); } inline bool wants_notices() - { return afb_verbose_notice(); } + { return AFB_SYSLOG_MASK_WANT_NOTICE(logmask()); } inline bool wants_infos() - { return afb_verbose_info(); } + { return AFB_SYSLOG_MASK_WANT_INFO(logmask()); } inline bool wants_debugs() - { return afb_verbose_debug(); } + { return AFB_SYSLOG_MASK_WANT_DEBUG(logmask()); } +#if AFB_BINDING_VERSION >= 3 +inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result, afb_api_t api), void *closure) +{ + afb_service_call(api, verb, args, callback, closure); +} + +template <class T> +inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, int iserror, struct json_object *result, afb_api_t api), T *closure) +{ + afb_service_call(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*,afb_api_t)>(callback), reinterpret_cast<void*>(closure)); +} +#else inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result), void *closure) { afb_service_call(api, verb, args, callback, closure); @@ -475,6 +517,7 @@ inline void call(const char *api, const char *verb, struct json_object *args, vo { afb_service_call(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*)>(callback), reinterpret_cast<void*>(closure)); } +#endif inline bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result) { @@ -563,31 +606,67 @@ constexpr afb_auth auth_and(const afb_auth &first, const afb_auth &next) return auth_and(&first, &next); } -constexpr afb_verb_v2 verb(const char *name, void (*callback)(afb_req), const char *info = nullptr, unsigned session = 0, const afb_auth *auth = nullptr) +constexpr afb_verb_t verb( + const char *name, + void (*callback)(afb_req_t), + const char *info = nullptr, + uint16_t session = 0, + const afb_auth *auth = nullptr +#if AFB_BINDING_VERSION >= 3 + , + bool glob = false, + void *vcbdata = nullptr +#endif +) { - afb_verb_v2 r = { 0, 0, 0, 0, 0 }; +#if AFB_BINDING_VERSION >= 3 + afb_verb_t r = { 0, 0, 0, 0, 0, 0, 0 }; +#else + afb_verb_t r = { 0, 0, 0, 0, 0 }; +#endif r.verb = name; r.callback = callback; r.info = info; r.session = session; r.auth = auth; +#if AFB_BINDING_VERSION >= 3 + r.glob = (unsigned)glob; + r.vcbdata = vcbdata; +#endif return r; } -constexpr afb_verb_v2 verbend() +constexpr afb_verb_t verbend() { - afb_verb_v2 r = { 0, 0, 0, 0, 0 }; - r.verb = nullptr; - r.callback = nullptr; - r.info = nullptr; - r.session = 0; - r.auth = nullptr; + afb_verb_t r = verb(nullptr, nullptr); return r; } -constexpr afb_binding_v2 binding(const char *name, const struct afb_verb_v2 *verbs, const char *info = nullptr, int (*init)() = nullptr, const char *specification = nullptr, void (*onevent)(const char*, struct json_object*) = nullptr, bool noconcurrency = false, int (*preinit)() = nullptr) +constexpr afb_binding_t binding( + const char *name, + const afb_verb_t *verbs, + const char *info = nullptr, +#if AFB_BINDING_VERSION >= 3 + int (*init)(afb_api_t) = nullptr, + const char *specification = nullptr, + void (*onevent)(afb_api_t, const char*, struct json_object*) = nullptr, + bool noconcurrency = false, + int (*preinit)(afb_api_t) = nullptr, + void *userdata = nullptr +#else + int (*init)() = nullptr, + const char *specification = nullptr, + void (*onevent)(const char*, struct json_object*) = nullptr, + bool noconcurrency = false, + int (*preinit)() = nullptr +#endif +) { - afb_binding_v2 r = { 0, 0, 0, 0, 0, 0, 0, 0 }; +#if AFB_BINDING_VERSION >= 3 + afb_binding_t r = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +#else + afb_binding_t r = { 0, 0, 0, 0, 0, 0, 0, 0 }; +#endif r.api = name; r.specification = specification; r.info = info; @@ -596,6 +675,9 @@ constexpr afb_binding_v2 binding(const char *name, const struct afb_verb_v2 *ver r.init = init; r.onevent = onevent; r.noconcurrency = noconcurrency ? 1 : 0; +#if AFB_BINDING_VERSION >= 3 + r.userdata = userdata; +#endif return r; }; diff --git a/include/afb/afb-daemon-itf-x1.h b/include/afb/afb-daemon-itf-x1.h new file mode 100644 index 00000000..3ca12eba --- /dev/null +++ b/include/afb/afb-daemon-itf-x1.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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> + +/* declaration of features of libsystemd */ +struct sd_event; +struct sd_bus; +struct afb_stored_req; +struct afb_req_x1; +struct afb_event_x1; +struct afb_api_x3; + +/** + * @deprecated use bindings version 3 + * + * Definition of the facilities provided by the daemon. + */ +struct afb_daemon_itf_x1 +{ + /** broadcasts evant 'name' with 'object' */ + int (*event_broadcast)(struct afb_api_x3 *closure, const char *name, struct json_object *object); + + /** gets the common systemd's event loop */ + struct sd_event *(*get_event_loop)(struct afb_api_x3 *closure); + + /** gets the common systemd's user d-bus */ + struct sd_bus *(*get_user_bus)(struct afb_api_x3 *closure); + + /** gets the common systemd's system d-bus */ + struct sd_bus *(*get_system_bus)(struct afb_api_x3 *closure); + + /** logging messages */ + void (*vverbose_v1)(struct afb_api_x3*closure, int level, const char *file, int line, const char *fmt, va_list args); + + /** creates an event of 'name' */ + struct afb_event_x1 (*event_make)(struct afb_api_x3 *closure, const char *name); + + /** get the file descriptor of the install directory */ + int (*rootdir_get_fd)(struct afb_api_x3 *closure); + + /** opens a file of the install directory */ + int (*rootdir_open_locale)(struct afb_api_x3 *closure, const char *filename, int flags, const char *locale); + + /** queue a job */ + int (*queue_job)(struct afb_api_x3 *closure, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout); + + /** logging messages */ + void (*vverbose_v2)(struct afb_api_x3*closure, int level, const char *file, int line, const char * func, const char *fmt, va_list args); + + /** retrieve a stored request */ + struct afb_req_x1 (*unstore_req)(struct afb_api_x3*closure, struct afb_stored_req *sreq); + + /** require an api */ + int (*require_api)(struct afb_api_x3*closure, const char *name, int initialized); + + /** aliases an api */ + int (*add_alias)(struct afb_api_x3*closure, const char *name, const char *as_name); + + /** creates a new api */ + struct afb_api_x3 *(*new_api)(struct afb_api_x3 *closure, const char *api, const char *info, int noconcurrency, int (*preinit)(void*, struct afb_api_x3 *), void *preinit_closure); +}; + +/** + * @deprecated use bindings version 3 + * + * Structure for accessing daemon. + * See also: afb_daemon_get_event_sender, afb_daemon_get_event_loop, afb_daemon_get_user_bus, afb_daemon_get_system_bus + */ +struct afb_daemon_x1 +{ + const struct afb_daemon_itf_x1 *itf; /**< the interfacing functions */ + struct afb_api_x3 *closure; /**< the closure when calling these functions */ +}; + diff --git a/include/afb/afb-daemon-itf.h b/include/afb/afb-daemon-itf.h deleted file mode 100644 index b8fa1931..00000000 --- a/include/afb/afb-daemon-itf.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2016, 2017, 2018 "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> - -/* declaration of features of libsystemd */ -struct sd_event; -struct sd_bus; -struct afb_stored_req; -struct afb_req; -struct afb_dynapi; - -/* - * Definition of the facilities provided by the daemon. - */ -struct afb_daemon_itf -{ - int (*event_broadcast)(void *closure, const char *name, struct json_object *object); /* broadcasts evant 'name' with 'object' */ - struct sd_event *(*get_event_loop)(void *closure); /* gets the common systemd's event loop */ - struct sd_bus *(*get_user_bus)(void *closure); /* gets the common systemd's user d-bus */ - struct sd_bus *(*get_system_bus)(void *closure); /* gets the common systemd's system d-bus */ - void (*vverbose_v1)(void*closure, int level, const char *file, int line, const char *fmt, va_list args); - struct afb_event (*event_make)(void *closure, const char *name); /* creates an event of 'name' */ - int (*rootdir_get_fd)(void *closure); - int (*rootdir_open_locale)(void *closure, const char *filename, int flags, const char *locale); - int (*queue_job)(void *closure, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout); - void (*vverbose_v2)(void*closure, int level, const char *file, int line, const char * func, const char *fmt, va_list args); - struct afb_req (*unstore_req)(void*closure, struct afb_stored_req *sreq); - int (*require_api)(void*closure, const char *name, int initialized); - int (*rename_api)(void*closure, const char *name); - int (*new_api)(void *closure, const char *api, const char *info, int noconcurrency, int (*preinit)(void*, struct afb_dynapi *), void *preinit_closure); -}; - -/* - * Structure for accessing daemon. - * See also: afb_daemon_get_event_sender, afb_daemon_get_event_loop, afb_daemon_get_user_bus, afb_daemon_get_system_bus - */ -struct afb_daemon -{ - const struct afb_daemon_itf *itf; /* the interfacing functions */ - void *closure; /* the closure when calling these functions */ -}; - diff --git a/include/afb/afb-daemon-v1.h b/include/afb/afb-daemon-v1.h index 5a78b15d..d84517d1 100644 --- a/include/afb/afb-daemon-v1.h +++ b/include/afb/afb-daemon-v1.h @@ -17,36 +17,44 @@ #pragma once -#include "afb-daemon-itf.h" +#include "afb-daemon-itf-x1.h" -/* +/** + * @deprecated use bindings version 3 + * * Retrieves the common systemd's event loop of AFB * 'daemon' MUST be the daemon given in interface when activating the binding. */ -static inline struct sd_event *afb_daemon_get_event_loop_v1(struct afb_daemon daemon) +static inline struct sd_event *afb_daemon_get_event_loop_v1(struct afb_daemon_x1 daemon) { return daemon.itf->get_event_loop(daemon.closure); } -/* +/** + * @deprecated use bindings version 3 + * * Retrieves the common systemd's user/session d-bus of AFB * 'daemon' MUST be the daemon given in interface when activating the binding. */ -static inline struct sd_bus *afb_daemon_get_user_bus_v1(struct afb_daemon daemon) +static inline struct sd_bus *afb_daemon_get_user_bus_v1(struct afb_daemon_x1 daemon) { return daemon.itf->get_user_bus(daemon.closure); } -/* +/** + * @deprecated use bindings version 3 + * * Retrieves the common systemd's system d-bus of AFB * 'daemon' MUST be the daemon given in interface when activating the binding. */ -static inline struct sd_bus *afb_daemon_get_system_bus_v1(struct afb_daemon daemon) +static inline struct sd_bus *afb_daemon_get_system_bus_v1(struct afb_daemon_x1 daemon) { return daemon.itf->get_system_bus(daemon.closure); } -/* +/** + * @deprecated use bindings version 3 + * * Broadcasts widely the event of 'name' with the data 'object'. * 'object' can be NULL. * 'daemon' MUST be the daemon given in interface when activating the binding. @@ -59,12 +67,14 @@ static inline struct sd_bus *afb_daemon_get_system_bus_v1(struct afb_daemon daem * * Returns the count of clients that received the event. */ -static inline int afb_daemon_broadcast_event_v1(struct afb_daemon daemon, const char *name, struct json_object *object) +static inline int afb_daemon_broadcast_event_v1(struct afb_daemon_x1 daemon, const char *name, struct json_object *object) { return daemon.itf->event_broadcast(daemon.closure, name, object); } -/* +/** + * @deprecated use bindings version 3 + * * Creates an event of 'name' and returns it. * 'daemon' MUST be the daemon given in interface when activating the binding. * @@ -72,12 +82,14 @@ static inline int afb_daemon_broadcast_event_v1(struct afb_daemon daemon, const * * See afb_event_is_valid to check if there is an error. */ -static inline struct afb_event afb_daemon_make_event_v1(struct afb_daemon daemon, const char *name) +static inline struct afb_event_x1 afb_daemon_make_event_v1(struct afb_daemon_x1 daemon, const char *name) { return daemon.itf->event_make(daemon.closure, name); } -/* +/** + * @deprecated use bindings version 3 + * * Send a message described by 'fmt' and following parameters * to the journal for the verbosity 'level'. * @@ -96,8 +108,8 @@ static inline struct afb_event afb_daemon_make_event_v1(struct afb_daemon daemon * INFO 6 Informational * DEBUG 7 Debug-level messages */ -static inline void afb_daemon_verbose_v1(struct afb_daemon daemon, int level, const char *file, int line, const char *fmt, ...) __attribute__((format(printf, 5, 6))); -static inline void afb_daemon_verbose_v1(struct afb_daemon daemon, int level, const char *file, int line, const char *fmt, ...) +static inline void afb_daemon_verbose_v1(struct afb_daemon_x1 daemon, int level, const char *file, int line, const char *fmt, ...) __attribute__((format(printf, 5, 6))); +static inline void afb_daemon_verbose_v1(struct afb_daemon_x1 daemon, int level, const char *file, int line, const char *fmt, ...) { va_list args; va_start(args, fmt); @@ -105,7 +117,9 @@ static inline void afb_daemon_verbose_v1(struct afb_daemon daemon, int level, co va_end(args); } -/* +/** + * @deprecated use bindings version 3 + * * Send a message described by 'fmt' and following parameters * to the journal for the verbosity 'level'. * @@ -124,8 +138,8 @@ static inline void afb_daemon_verbose_v1(struct afb_daemon daemon, int level, co * INFO 6 Informational * DEBUG 7 Debug-level messages */ -static inline void afb_daemon_verbose2_v1(struct afb_daemon daemon, int level, const char *file, int line, const char *func, const char *fmt, ...) __attribute__((format(printf, 6, 7))); -static inline void afb_daemon_verbose2_v1(struct afb_daemon daemon, int level, const char *file, int line, const char *func, const char *fmt, ...) +static inline void afb_daemon_verbose2_v1(struct afb_daemon_x1 daemon, int level, const char *file, int line, const char *func, const char *fmt, ...) __attribute__((format(printf, 6, 7))); +static inline void afb_daemon_verbose2_v1(struct afb_daemon_x1 daemon, int level, const char *file, int line, const char *func, const char *fmt, ...) { va_list args; va_start(args, fmt); @@ -133,26 +147,34 @@ static inline void afb_daemon_verbose2_v1(struct afb_daemon daemon, int level, c va_end(args); } -/* +/** + * @deprecated use bindings version 3 + * * Get the root directory file descriptor. This file descriptor can * be used with functions 'openat', 'fstatat', ... + * + * Returns the file descriptor or -1 in case of error. */ -static inline int afb_daemon_rootdir_get_fd_v1(struct afb_daemon daemon) +static inline int afb_daemon_rootdir_get_fd_v1(struct afb_daemon_x1 daemon) { return daemon.itf->rootdir_get_fd(daemon.closure); } -/* - * Opens 'filename' within the root directory with 'flags' (see function openat) +/** + * @deprecated use bindings version 3 + * * using the 'locale' definition (example: "jp,en-US") that can be NULL. + * * Returns the file descriptor or -1 in case of error. */ -static inline int afb_daemon_rootdir_open_locale_v1(struct afb_daemon daemon, const char *filename, int flags, const char *locale) +static inline int afb_daemon_rootdir_open_locale_v1(struct afb_daemon_x1 daemon, const char *filename, int flags, const char *locale) { return daemon.itf->rootdir_open_locale(daemon.closure, filename, flags, locale); } -/* +/** + * @deprecated use bindings version 3 + * * Queue the job defined by 'callback' and 'argument' for being executed asynchronously * in this thread (later) or in an other thread. * If 'group' is not NUL, the jobs queued with a same value (as the pointer value 'group') @@ -165,39 +187,52 @@ static inline int afb_daemon_rootdir_open_locale_v1(struct afb_daemon daemon, co * * Returns 0 in case of success or -1 in case of error. */ -static inline int afb_daemon_queue_job_v1(struct afb_daemon daemon, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout) +static inline int afb_daemon_queue_job_v1(struct afb_daemon_x1 daemon, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout) { return daemon.itf->queue_job(daemon.closure, callback, argument, group, timeout); } -/* +/** + * @deprecated use bindings version 3 + * * Tells that it requires the API of "name" to exist * and if 'initialized' is not null to be initialized. * Calling this function is only allowed within init. + * * Returns 0 in case of success or -1 in case of error. */ -static inline int afb_daemon_require_api_v1(struct afb_daemon daemon, const char *name, int initialized) +static inline int afb_daemon_require_api_v1(struct afb_daemon_x1 daemon, const char *name, int initialized) { return daemon.itf->require_api(daemon.closure, name, initialized); } -/* - * Set the name of the API to 'name'. +/** + * @deprecated use bindings version 3 + * + * Create an aliased name 'as_name' for the api 'name'. * Calling this function is only allowed within preinit. + * * Returns 0 in case of success or -1 in case of error. */ -static inline int afb_daemon_rename_api_v1(struct afb_daemon daemon, const char *name) +static inline int afb_daemon_add_alias_v1(struct afb_daemon_x1 daemon, const char *name, const char *as_name) { - return daemon.itf->rename_api(daemon.closure, name); + return daemon.itf->add_alias(daemon.closure, name, as_name); } +/** + * @deprecated use bindings version 3 + * + * Creates a new api of name 'api' with brief 'info'. + * + * Returns 0 in case of success or -1 in case of error. + */ static inline int afb_daemon_new_api_v1( - struct afb_daemon daemon, + struct afb_daemon_x1 daemon, const char *api, const char *info, int noconcurrency, - int (*preinit)(void*, struct afb_dynapi *), + int (*preinit)(void*, struct afb_api_x3 *), void *closure) { - return daemon.itf->new_api(daemon.closure, api, info, noconcurrency, preinit, closure); + return -!daemon.itf->new_api(daemon.closure, api, info, noconcurrency, preinit, closure); } diff --git a/include/afb/afb-daemon-v2.h b/include/afb/afb-daemon-v2.h index 4b8399c4..f3c2c904 100644 --- a/include/afb/afb-daemon-v2.h +++ b/include/afb/afb-daemon-v2.h @@ -17,9 +17,11 @@ #pragma once -#include "afb-daemon-itf.h" +#include "afb-daemon-itf-x1.h" -/* +/** + * @deprecated use bindings version 3 + * * Retrieves the common systemd's event loop of AFB */ static inline struct sd_event *afb_daemon_get_event_loop_v2() @@ -27,7 +29,9 @@ static inline struct sd_event *afb_daemon_get_event_loop_v2() return afb_get_daemon_v2().itf->get_event_loop(afb_get_daemon_v2().closure); } -/* +/** + * @deprecated use bindings version 3 + * * Retrieves the common systemd's user/session d-bus of AFB */ static inline struct sd_bus *afb_daemon_get_user_bus_v2() @@ -35,7 +39,9 @@ static inline struct sd_bus *afb_daemon_get_user_bus_v2() return afb_get_daemon_v2().itf->get_user_bus(afb_get_daemon_v2().closure); } -/* +/** + * @deprecated use bindings version 3 + * * Retrieves the common systemd's system d-bus of AFB */ static inline struct sd_bus *afb_daemon_get_system_bus_v2() @@ -43,7 +49,9 @@ static inline struct sd_bus *afb_daemon_get_system_bus_v2() return afb_get_daemon_v2().itf->get_system_bus(afb_get_daemon_v2().closure); } -/* +/** + * @deprecated use bindings version 3 + * * Broadcasts widely the event of 'name' with the data 'object'. * 'object' can be NULL. * @@ -60,19 +68,23 @@ static inline int afb_daemon_broadcast_event_v2(const char *name, struct json_ob return afb_get_daemon_v2().itf->event_broadcast(afb_get_daemon_v2().closure, name, object); } -/* +/** + * @deprecated use bindings version 3 + * * Creates an event of 'name' and returns it. * * Calling this function is only forbidden during preinit. * * See afb_event_is_valid to check if there is an error. */ -static inline struct afb_event afb_daemon_make_event_v2(const char *name) +static inline struct afb_event_x1 afb_daemon_make_event_v2(const char *name) { return afb_get_daemon_v2().itf->event_make(afb_get_daemon_v2().closure, name); } -/* +/** + * @deprecated use bindings version 3 + * * Send a message described by 'fmt' and following parameters * to the journal for the verbosity 'level'. * @@ -98,18 +110,25 @@ static inline void afb_daemon_verbose_v2(int level, const char *file, int line, va_end(args); } -/* +/** + * @deprecated use bindings version 3 + * * Get the root directory file descriptor. This file descriptor can * be used with functions 'openat', 'fstatat', ... + * + * Returns the file descriptor or -1 in case of error. */ static inline int afb_daemon_rootdir_get_fd_v2() { return afb_get_daemon_v2().itf->rootdir_get_fd(afb_get_daemon_v2().closure); } -/* +/** + * @deprecated use bindings version 3 + * * Opens 'filename' within the root directory with 'flags' (see function openat) * using the 'locale' definition (example: "jp,en-US") that can be NULL. + * * Returns the file descriptor or -1 in case of error. */ static inline int afb_daemon_rootdir_open_locale_v2(const char *filename, int flags, const char *locale) @@ -117,7 +136,9 @@ static inline int afb_daemon_rootdir_open_locale_v2(const char *filename, int fl return afb_get_daemon_v2().itf->rootdir_open_locale(afb_get_daemon_v2().closure, filename, flags, locale); } -/* +/** + * @deprecated use bindings version 3 + * * Queue the job defined by 'callback' and 'argument' for being executed asynchronously * in this thread (later) or in an other thread. * If 'group' is not NUL, the jobs queued with a same value (as the pointer value 'group') @@ -135,22 +156,27 @@ static inline int afb_daemon_queue_job_v2(void (*callback)(int signum, void *arg return afb_get_daemon_v2().itf->queue_job(afb_get_daemon_v2().closure, callback, argument, group, timeout); } -/* +/** + * @deprecated use bindings version 3 + * * Retrieves the afb_req stored at 'sreq'. * Returns the stored request. * The count of reference is UNCHANGED, thus, the * function 'afb_req_unref' should be called on the result * after that the asynchronous reply if sent. */ -static inline struct afb_req afb_daemon_unstore_req_v2(struct afb_stored_req *sreq) +static inline struct afb_req_x1 afb_daemon_unstore_req_v2(struct afb_stored_req *sreq) { return afb_get_daemon_v2().itf->unstore_req(afb_get_daemon_v2().closure, sreq); } -/* +/** + * @deprecated use bindings version 3 + * * Tells that it requires the API of "name" to exist * and if 'initialized' is not null to be initialized. * Calling this function is only allowed within init. + * * Returns 0 in case of success or -1 in case of error. */ static inline int afb_daemon_require_api_v2(const char *name, int initialized) @@ -158,23 +184,33 @@ static inline int afb_daemon_require_api_v2(const char *name, int initialized) return afb_get_daemon_v2().itf->require_api(afb_get_daemon_v2().closure, name, initialized); } -/* - * Set the name of the API to 'name'. +/** + * @deprecated use bindings version 3 + * + * Create an aliased name 'as_name' for the api 'name'. * Calling this function is only allowed within preinit. + * * Returns 0 in case of success or -1 in case of error. */ -static inline int afb_daemon_rename_api_v2(const char *name) +static inline int afb_daemon_add_alias_v2(const char *name, const char *as_name) { - return afb_get_daemon_v2().itf->rename_api(afb_get_daemon_v2().closure, name); + return afb_get_daemon_v2().itf->add_alias(afb_get_daemon_v2().closure, name, as_name); } +/** + * @deprecated use bindings version 3 + * + * Creates a new api of name 'api' with brief 'info'. + * + * Returns 0 in case of success or -1 in case of error. + */ static inline int afb_daemon_new_api_v2( const char *api, const char *info, int noconcurrency, - int (*preinit)(void*, struct afb_dynapi *), + int (*preinit)(void*, struct afb_api_x3 *), void *closure) { - return afb_get_daemon_v2().itf->new_api(afb_get_daemon_v2().closure, api, info, noconcurrency, preinit, closure); + return -!(afb_get_daemon_v2().itf->new_api(afb_get_daemon_v2().closure, api, info, noconcurrency, preinit, closure)); } diff --git a/include/afb/afb-dynapi-itf.h b/include/afb/afb-dynapi-itf.h deleted file mode 100644 index 979088d6..00000000 --- a/include/afb/afb-dynapi-itf.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2016, 2017, 2018 "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 - -/* declared here */ -struct afb_dynapi; -struct afb_dynapi_itf; - -/* referenced here */ -#include <stdarg.h> -struct sd_event; -struct sd_bus; -struct afb_request; -struct afb_eventid; -struct afb_auth; -struct afb_verb_v2; - -/* - * structure for the dynapi - */ -struct afb_dynapi -{ - /* interface for the dynapi */ - const struct afb_dynapi_itf *itf; - - /* user defined data */ - void *userdata; - - /* current verbosity level */ - int verbosity; - - /* the name of the api */ - const char *apiname; -}; - -/* - * Definition of the interface for the API - */ -struct afb_dynapi_itf -{ - /* CAUTION: respect the order, add at the end */ - - void (*vverbose)( - void *dynapi, - int level, - const char *file, - int line, - const char * func, - const char *fmt, - va_list args); - - /* gets the common systemd's event loop */ - struct sd_event *(*get_event_loop)( - void *dynapi); - - /* gets the common systemd's user d-bus */ - struct sd_bus *(*get_user_bus)( - void *dynapi); - - /* gets the common systemd's system d-bus */ - struct sd_bus *(*get_system_bus)( - void *dynapi); - - int (*rootdir_get_fd)( - void *dynapi); - - int (*rootdir_open_locale)( - void *dynapi, - const char *filename, - int flags, - const char *locale); - - int (*queue_job)( - void *dynapi, - void (*callback)(int signum, void *arg), - void *argument, - void *group, - int timeout); - - int (*require_api)( - void *dynapi, - const char *name, - int initialized); - - int (*rename_api)( - void *dynapi, - const char *name); - - /* broadcasts event 'name' with 'object' */ - int (*event_broadcast)( - void *dynapi, - const char *name, - struct json_object *object); - - /* creates an event of 'name' */ - struct afb_eventid *(*eventid_make)( - void *dynapi, - const char *name); - - void (*call)( - struct afb_dynapi *dynapi, - const char *api, - const char *verb, - struct json_object *args, - void (*callback)(void*, int, struct json_object*, struct afb_dynapi *), - void *callback_closure); - - int (*call_sync)( - void *dynapi, - const char *api, - const char *verb, - struct json_object *args, - struct json_object **result); - - int (*api_new_api)( - void *dynapi, - const char *api, - const char *info, - int noconcurrency, - int (*preinit)(void*, struct afb_dynapi *), - void *closure); - - int (*api_set_verbs_v2)( - struct afb_dynapi *dynapi, - const struct afb_verb_v2 *verbs); - - int (*api_add_verb)( - struct afb_dynapi *dynapi, - const char *verb, - const char *info, - void (*callback)(struct afb_request *request), - void *vcbdata, - const struct afb_auth *auth, - uint32_t session); - - int (*api_sub_verb)( - struct afb_dynapi *dynapi, - const char *verb); - - int (*api_set_on_event)( - struct afb_dynapi *dynapi, - void (*onevent)(struct afb_dynapi *dynapi, const char *event, struct json_object *object)); - - int (*api_set_on_init)( - struct afb_dynapi *dynapi, - int (*oninit)(struct afb_dynapi *dynapi)); - - void (*api_seal)( - struct afb_dynapi *dynapi); -}; - diff --git a/include/afb/afb-dynapi-legacy.h b/include/afb/afb-dynapi-legacy.h new file mode 100644 index 00000000..ffa0d92a --- /dev/null +++ b/include/afb/afb-dynapi-legacy.h @@ -0,0 +1,191 @@ + +/* + * Copyright (C) 2018 "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 + +/***************************************************************************************************/ + +#define afb_dynapi afb_api_x3 +#define afb_dynapi_itf afb_api_x3_itf + +#define afb_request afb_req_x2 +#define afb_request_get_dynapi afb_req_x2_get_api +#define afb_request_get_vcbdata afb_req_x2_get_vcbdata +#define afb_request_get_api afb_req_x2_get_called_api +#define afb_request_get_verb afb_req_x2_get_called_verb +#define afb_request_wants_log_level afb_req_x2_wants_log_level + +#define afb_request_get afb_req_x2_get +#define afb_request_value afb_req_x2_value +#define afb_request_path afb_req_x2_path +#define afb_request_json afb_req_x2_json +#define afb_request_reply afb_req_x2_reply +#define afb_request_reply_f afb_req_x2_reply_f +#define afb_request_reply_v afb_req_x2_reply_v +#define afb_request_success(r,o,i) afb_req_x2_reply(r,o,0,i) +#define afb_request_success_f(r,o,...) afb_req_x2_reply_f(r,o,0,__VA_ARGS__) +#define afb_request_success_v(r,o,f,v) afb_req_x2_reply_v(r,o,0,f,v) +#define afb_request_fail(r,e,i) afb_req_x2_reply(r,0,e,i) +#define afb_request_fail_f(r,e,f,...) afb_req_x2_reply_f(r,0,e,f,__VA_ARGS__) +#define afb_request_fail_v(r,e,f,v) afb_req_x2_reply_v(r,0,e,f,v) +#define afb_request_context_get afb_req_x2_context_get +#define afb_request_context_set afb_req_x2_context_set +#define afb_request_context afb_req_x2_context +#define afb_request_context_clear afb_req_x2_context_clear +#define afb_request_addref afb_req_x2_addref +#define afb_request_unref afb_req_x2_unref +#define afb_request_session_close afb_req_x2_session_close +#define afb_request_session_set_LOA afb_req_x2_session_set_LOA +#define afb_request_subscribe afb_req_x2_subscribe +#define afb_request_unsubscribe afb_req_x2_unsubscribe +#define afb_request_subcall afb_req_x2_subcall_legacy +#define afb_request_subcall_sync afb_req_x2_subcall_sync_legacy +#define afb_request_verbose afb_req_x2_verbose +#define afb_request_has_permission afb_req_x2_has_permission +#define afb_request_get_application_id afb_req_x2_get_application_id +#define afb_request_get_uid afb_req_x2_get_uid +#define afb_request_get_client_info afb_req_x2_get_client_info + +#define afb_dynapi_name afb_api_x3_name +#define afb_dynapi_get_userdata afb_api_x3_get_userdata +#define afb_dynapi_set_userdata afb_api_x3_set_userdata +#define afb_dynapi_wants_log_level afb_api_x3_wants_log_level + +#define afb_dynapi_verbose afb_api_x3_verbose +#define afb_dynapi_vverbose afb_api_x3_vverbose +#define afb_dynapi_get_event_loop afb_api_x3_get_event_loop +#define afb_dynapi_get_user_bus afb_api_x3_get_user_bus +#define afb_dynapi_get_system_bus afb_api_x3_get_system_bus +#define afb_dynapi_rootdir_get_fd afb_api_x3_rootdir_get_fd +#define afb_dynapi_rootdir_open_locale afb_api_x3_rootdir_open_locale +#define afb_dynapi_queue_job afb_api_x3_queue_job +#define afb_dynapi_require_api afb_api_x3_require_api +#define afb_dynapi_rename_api afb_api_x3_add_alias +#define afb_dynapi_broadcast_event afb_api_x3_broadcast_event +#define afb_dynapi_make_eventid afb_api_x3_make_event_x2 +#define afb_dynapi_call afb_api_x3_call_legacy +#define afb_dynapi_call_sync afb_api_x3_call_sync_legacy +#define afb_dynapi_new_api(...) (-!afb_api_x3_new_api(__VA_ARGS__)) +#define afb_dynapi_set_verbs_v2 afb_api_x3_set_verbs_v2 +#define afb_dynapi_add_verb(a,b,c,d,e,f,g) afb_api_x3_add_verb(a,b,c,d,e,f,g,0) +#define afb_dynapi_sub_verb(a,b) afb_api_x3_del_verb(a,b,NULL) +#define afb_dynapi_on_event afb_api_x3_on_event +#define afb_dynapi_on_init afb_api_x3_on_init +#define afb_dynapi_seal afb_api_x3_seal + +#define afb_eventid_broadcast afb_event_x2_broadcast +#define afb_eventid_push afb_event_x2_push +#define afb_eventid_name afb_event_x2_name +#define afb_eventid_unref afb_event_x2_unref +#define afb_eventid_addref afb_event_x2_addref + +#define afb_eventid afb_event_x2 +#define afb_eventid_is_valid afb_event_x2_is_valid +#define afb_eventid_broadcast afb_event_x2_broadcast +#define afb_eventid_push afb_event_x2_push +#define afb_eventid_drop afb_event_x2_unref +#define afb_eventid_name afb_event_x2_name +#define afb_eventid_unref afb_event_x2_unref +#define afb_eventid_addref afb_event_x2_addref + +/* + * The function afbBindingVdyn if exported allows to create + * pure dynamic bindings. When the binding is loaded, it receives + * a virtual dynapi that can be used to create apis. The + * given API can not be used except for creating dynamic apis. + */ +extern int afbBindingVdyn(struct afb_dynapi *dynapi); + +/* + * Macros for logging messages + */ +/* macro for setting file, line and function automatically */ +# if !defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DETAILS) +#define AFB_REQUEST_VERBOSE(req,level,...) afb_req_x2_verbose(req,level,__FILE__,__LINE__,__func__,__VA_ARGS__) +#else +#define AFB_REQUEST_VERBOSE(req,level,...) afb_req_x2_verbose(req,level,NULL,0,NULL,__VA_ARGS__) +#endif + +#if defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DATA) + +# define _AFB_DYNAPI_LOGGING_(llevel,dynapi,...) \ + do{ \ + if(_AFB_SYSLOG_MASK_WANT_(dynapi->logmask,llevel)) {\ + if (llevel <= AFB_VERBOSITY_LEVEL_ERROR) \ + afb_dynapi_verbose(dynapi,llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ + else \ + afb_dynapi_verbose(dynapi,llevel,__FILE__,__LINE__,NULL,NULL); \ + } \ + }while(0) +# define _AFB_REQUEST_LOGGING_(llevel,request,...) \ + do{ \ + if(request->_AFB_SYSLOG_MASK_WANT_(dynapi->logmask,llevel)) \ + afb_request_verbose(request,llevel,__FILE__,__LINE__,NULL,NULL); \ + }while(0) + +#elif defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DETAILS) + +# define _AFB_DYNAPI_LOGGING_(llevel,dynapi,...) \ + do{ \ + if(_AFB_SYSLOG_MASK_WANT_(dynapi->logmask,llevel)) \ + afb_dynapi_verbose(dynapi,llevel,NULL,0,NULL,__VA_ARGS__); \ + }while(0) +# define _AFB_REQUEST_LOGGING_(llevel,request,...) \ + do{ \ + if(request->_AFB_SYSLOG_MASK_WANT_(dynapi->logmask,llevel)) \ + afb_request_verbose(request,llevel,NULL,0,NULL,__VA_ARGS__); \ + }while(0) + +#else + +# define _AFB_DYNAPI_LOGGING_(llevel,dynapi,...) \ + do{ \ + if(AFB_SYSLOG_MASK_WANT(dynapi->logmask,llevel)) \ + afb_dynapi_verbose(dynapi,llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ + }while(0) +# define _AFB_REQUEST_LOGGING_(llevel,request,...) \ + do{ \ + if(AFB_SYSLOG_MASK_WANT(request->api->logmask,llevel)) \ + afb_request_verbose(request,llevel,__FILE__,__LINE__,__func__,__VA_ARGS__); \ + }while(0) + +#endif + +#define AFB_DYNAPI_ERROR(...) _AFB_DYNAPI_LOGGING_(AFB_SYSLOG_LEVEL_ERROR,__VA_ARGS__) +#define AFB_DYNAPI_WARNING(...) _AFB_DYNAPI_LOGGING_(AFB_SYSLOG_LEVEL_WARNING,__VA_ARGS__) +#define AFB_DYNAPI_NOTICE(...) _AFB_DYNAPI_LOGGING_(AFB_SYSLOG_LEVEL_NOTICE,__VA_ARGS__) +#define AFB_DYNAPI_INFO(...) _AFB_DYNAPI_LOGGING_(AFB_SYSLOG_LEVEL_INFO,__VA_ARGS__) +#define AFB_DYNAPI_DEBUG(...) _AFB_DYNAPI_LOGGING_(AFB_SYSLOG_LEVEL_DEBUG,__VA_ARGS__) +#define AFB_REQUEST_ERROR(...) _AFB_REQUEST_LOGGING_(AFB_SYSLOG_LEVEL_ERROR,__VA_ARGS__) +#define AFB_REQUEST_WARNING(...) _AFB_REQUEST_LOGGING_(AFB_SYSLOG_LEVEL_WARNING,__VA_ARGS__) +#define AFB_REQUEST_NOTICE(...) _AFB_REQUEST_LOGGING_(AFB_SYSLOG_LEVEL_NOTICE,__VA_ARGS__) +#define AFB_REQUEST_INFO(...) _AFB_REQUEST_LOGGING_(AFB_SYSLOG_LEVEL_INFO,__VA_ARGS__) +#define AFB_REQUEST_DEBUG(...) _AFB_REQUEST_LOGGING_(AFB_SYSLOG_LEVEL_DEBUG,__VA_ARGS__) + +typedef struct afb_eventid afb_eventid; +typedef struct afb_dynapi afb_dynapi; +typedef struct afb_request afb_request; + +#define _AFB_SYSLOG_LEVEL_EMERGENCY_ AFB_SYSLOG_LEVEL_EMERGENCY +#define _AFB_SYSLOG_LEVEL_ALERT_ AFB_SYSLOG_LEVEL_ALERT +#define _AFB_SYSLOG_LEVEL_CRITICAL_ AFB_SYSLOG_LEVEL_CRITICAL +#define _AFB_SYSLOG_LEVEL_ERROR_ AFB_SYSLOG_LEVEL_ERROR +#define _AFB_SYSLOG_LEVEL_WARNING_ AFB_SYSLOG_LEVEL_WARNING +#define _AFB_SYSLOG_LEVEL_NOTICE_ AFB_SYSLOG_LEVEL_NOTICE +#define _AFB_SYSLOG_LEVEL_INFO_ AFB_SYSLOG_LEVEL_INFO +#define _AFB_SYSLOG_LEVEL_DEBUG_ AFB_SYSLOG_LEVEL_DEBUG diff --git a/include/afb/afb-dynapi.h b/include/afb/afb-dynapi.h deleted file mode 100644 index 2a26915c..00000000 --- a/include/afb/afb-dynapi.h +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (C) 2016, 2017, 2018 "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 "afb-dynapi-itf.h" - -static inline const char *afb_dynapi_name(struct afb_dynapi *dynapi) -{ - return dynapi->apiname; -} - -static inline void *afb_dynapi_get_userdata(struct afb_dynapi *dynapi) -{ - return dynapi->userdata; -} - -static inline void afb_dynapi_set_userdata(struct afb_dynapi *dynapi, void *userdata) -{ - dynapi->userdata = userdata; -} - -/* - * Send a message described by 'fmt' and following parameters - * to the journal for the verbosity 'level'. - * - * 'file', 'line' and 'func' are indicators of position of the code in source files - * (see macros __FILE__, __LINE__ and __func__). - * - * - * 'level' is defined by syslog standard: - * EMERGENCY 0 System is unusable - * ALERT 1 Action must be taken immediately - * CRITICAL 2 Critical conditions - * ERROR 3 Error conditions - * WARNING 4 Warning conditions - * NOTICE 5 Normal but significant condition - * INFO 6 Informational - * DEBUG 7 Debug-level messages - */ -static inline void afb_dynapi_verbose(struct afb_dynapi *dynapi, int level, const char *file, int line, const char *func, const char *fmt, ...) __attribute__((format(printf, 6, 7))); -static inline void afb_dynapi_verbose(struct afb_dynapi *dynapi, int level, const char *file, int line, const char *func, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - dynapi->itf->vverbose(dynapi, level, file, line, func, fmt, args); - va_end(args); -} -static inline void afb_dynapi_vverbose(struct afb_dynapi *dynapi, int level, const char *file, int line, const char *func, const char *fmt, va_list args) -{ - dynapi->itf->vverbose(dynapi, level, file, line, func, fmt, args); -} - -/* - * Retrieves the common systemd's event loop of AFB - */ -static inline struct sd_event *afb_dynapi_get_event_loop(struct afb_dynapi *dynapi) -{ - return dynapi->itf->get_event_loop(dynapi); -} - -/* - * Retrieves the common systemd's user/session d-bus of AFB - */ -static inline struct sd_bus *afb_dynapi_get_user_bus(struct afb_dynapi *dynapi) -{ - return dynapi->itf->get_user_bus(dynapi); -} - -/* - * Retrieves the common systemd's system d-bus of AFB - */ -static inline struct sd_bus *afb_dynapi_get_system_bus(struct afb_dynapi *dynapi) -{ - return dynapi->itf->get_system_bus(dynapi); -} - -/* - * Get the root directory file descriptor. This file descriptor can - * be used with functions 'openat', 'fstatat', ... - */ -static inline int afb_dynapi_rootdir_get_fd(struct afb_dynapi *dynapi) -{ - return dynapi->itf->rootdir_get_fd(dynapi); -} - -/* - * Opens 'filename' within the root directory with 'flags' (see function openat) - * using the 'locale' definition (example: "jp,en-US") that can be NULL. - * Returns the file descriptor or -1 in case of error. - */ -static inline int afb_dynapi_rootdir_open_locale(struct afb_dynapi *dynapi, const char *filename, int flags, const char *locale) -{ - return dynapi->itf->rootdir_open_locale(dynapi, filename, flags, locale); -} - -/* - * Queue the job defined by 'callback' and 'argument' for being executed asynchronously - * in this thread (later) or in an other thread. - * If 'group' is not NUL, the jobs queued with a same value (as the pointer value 'group') - * are executed in sequence in the order of there submission. - * If 'timeout' is not 0, it represent the maximum execution time for the job in seconds. - * At first, the job is called with 0 as signum and the given argument. - * The job is executed with the monitoring of its time and some signals like SIGSEGV and - * SIGFPE. When a such signal is catched, the job is terminated and reexecuted but with - * signum being the signal number (SIGALRM when timeout expired). - * - * Returns 0 in case of success or -1 in case of error. - */ -static inline int afb_dynapi_queue_job(struct afb_dynapi *dynapi, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout) -{ - return dynapi->itf->queue_job(dynapi, callback, argument, group, timeout); -} - -/* - * Tells that it requires the API of "name" to exist - * and if 'initialized' is not null to be initialized. - * Calling this function is only allowed within init. - * Returns 0 in case of success or -1 in case of error. - */ -static inline int afb_dynapi_require_api(struct afb_dynapi *dynapi, const char *name, int initialized) -{ - return dynapi->itf->require_api(dynapi, name, initialized); -} - -/* - * Set the name of the API to 'name'. - * Calling this function is only allowed within preinit. - * Returns 0 in case of success or -1 in case of error. - */ -static inline int afb_dynapi_rename_api(struct afb_dynapi *dynapi, const char *name) -{ - return dynapi->itf->rename_api(dynapi, name); -} - -/* - * Broadcasts widely the event of 'name' with the data 'object'. - * 'object' can be NULL. - * - * For convenience, the function calls 'json_object_put' for 'object'. - * Thus, in the case where 'object' should remain available after - * the function returns, the function 'json_object_get' shall be used. - * - * Calling this function is only forbidden during preinit. - * - * Returns the count of clients that received the event. - */ -static inline int afb_dynapi_broadcast_event(struct afb_dynapi *dynapi, const char *name, struct json_object *object) -{ - return dynapi->itf->event_broadcast(dynapi, name, object); -} - -/* - * Creates an event of 'name' and returns it. - * - * Calling this function is only forbidden during preinit. - * - * See afb_event_is_valid to check if there is an error. - */ -static inline struct afb_eventid *afb_dynapi_make_eventid(struct afb_dynapi *dynapi, const char *name) -{ - return dynapi->itf->eventid_make(dynapi, name); -} - -/** - * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. - * The result of the call is delivered to the 'callback' function with the 'callback_closure'. - * - * For convenience, the function calls 'json_object_put' for 'args'. - * Thus, in the case where 'args' should remain available after - * the function returns, the function 'json_object_get' shall be used. - * - * The 'callback' receives 3 arguments: - * 1. 'closure' the user defined closure pointer 'callback_closure', - * 2. 'status' a status being 0 on success or negative when an error occured, - * 2. 'result' the resulting data as a JSON object. - * - * @param dynapi The dynapi - * @param api The api name of the method to call - * @param verb The verb name of the method to call - * @param args The arguments to pass to the method - * @param callback The to call on completion - * @param callback_closure The closure to pass to the callback - * - * @see also 'afb_req_subcall' - */ -static inline void afb_dynapi_call( - struct afb_dynapi *dynapi, - const char *api, - const char *verb, - struct json_object *args, - void (*callback)(void *closure, int status, struct json_object *result, struct afb_dynapi *dynapi), - void *callback_closure) -{ - dynapi->itf->call(dynapi, api, verb, args, callback, callback_closure); -} - -/** - * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. - * 'result' will receive the response. - * - * For convenience, the function calls 'json_object_put' for 'args'. - * Thus, in the case where 'args' should remain available after - * the function returns, the function 'json_object_get' shall be used. - * - * @param dynapi The dynapi - * @param api The api name of the method to call - * @param verb The verb name of the method to call - * @param args The arguments to pass to the method - * @param result Where to store the result - should call json_object_put on it - - * - * @returns 0 in case of success or a negative value in case of error. - * - * @see also 'afb_req_subcall' - */ -static inline int afb_dynapi_call_sync( - struct afb_dynapi *dynapi, - const char *api, - const char *verb, - struct json_object *args, - struct json_object **result) -{ - return dynapi->itf->call_sync(dynapi, api, verb, args, result); -} - - -static inline int afb_dynapi_new_api( - struct afb_dynapi *dynapi, - const char *api, - const char *info, - int noconcurrency, - int (*preinit)(void*, struct afb_dynapi *), - void *closure) -{ - return dynapi->itf->api_new_api(dynapi, api, info, noconcurrency, preinit, closure); -} - -static inline int afb_dynapi_set_verbs_v2( - struct afb_dynapi *dynapi, - const struct afb_verb_v2 *verbs) -{ - return dynapi->itf->api_set_verbs_v2(dynapi, verbs); -} - -static inline int afb_dynapi_add_verb( - struct afb_dynapi *dynapi, - const char *verb, - const char *info, - void (*callback)(struct afb_request *request), - void *vcbdata, - const struct afb_auth *auth, - uint32_t session) -{ - return dynapi->itf->api_add_verb(dynapi, verb, info, callback, vcbdata, auth, session); -} - - -static inline int afb_dynapi_sub_verb( - struct afb_dynapi *dynapi, - const char *verb) -{ - return dynapi->itf->api_sub_verb(dynapi, verb); -} - - -static inline int afb_dynapi_on_event( - struct afb_dynapi *dynapi, - void (*onevent)(struct afb_dynapi *dynapi, const char *event, struct json_object *object)) -{ - return dynapi->itf->api_set_on_event(dynapi, onevent); -} - - -static inline int afb_dynapi_on_init( - struct afb_dynapi *dynapi, - int (*oninit)(struct afb_dynapi *dynapi)) -{ - return dynapi->itf->api_set_on_init(dynapi, oninit); -} - - -static inline void afb_dynapi_seal( - struct afb_dynapi *dynapi) -{ - dynapi->itf->api_seal(dynapi); -} - - diff --git a/include/afb/afb-event-x1-itf.h b/include/afb/afb-event-x1-itf.h new file mode 100644 index 00000000..afd033b8 --- /dev/null +++ b/include/afb/afb-event-x1-itf.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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 "afb-event-x2-itf.h" + +/** + * @deprecated use bindings version 3 + * + * Describes the request of afb-daemon for bindings + */ +struct afb_event_x1 +{ + const struct afb_event_x2_itf *itf; /**< the interface to use */ + struct afb_event_x2 *closure; /**< the closure argument for functions of 'itf' */ +}; + diff --git a/include/afb/afb-event.h b/include/afb/afb-event-x1.h index 0876d8cf..1fc7696f 100644 --- a/include/afb/afb-event.h +++ b/include/afb/afb-event-x1.h @@ -17,36 +17,33 @@ #pragma once -#include "afb-eventid-itf.h" +#include "afb-event-x1-itf.h" -/* - * Describes the request of afb-daemon for bindings - */ -struct afb_event -{ - const struct afb_eventid_itf *itf; /* the interface to use */ - struct afb_eventid *closure; /* the closure argument for functions of 'itf' */ -}; - -/* +/** + * @deprecated use bindings version 3 + * * Converts the 'event' to an afb_eventid. */ -static inline struct afb_eventid *afb_event_to_eventid(struct afb_event event) +static inline struct afb_event_x2 *afb_event_x1_to_event_x2(struct afb_event_x1 event) { return event.closure; } -/* +/** + * @deprecated use bindings version 3 + * * Checks wether the 'event' is valid or not. * * Returns 0 if not valid or 1 if valid. */ -static inline int afb_event_is_valid(struct afb_event event) +static inline int afb_event_x1_is_valid(struct afb_event_x1 event) { return !!event.itf; } -/* +/** + * @deprecated use bindings version 3 + * * Broadcasts widely the 'event' with the data 'object'. * 'object' can be NULL. * @@ -56,12 +53,14 @@ static inline int afb_event_is_valid(struct afb_event event) * * Returns the count of clients that received the event. */ -static inline int afb_event_broadcast(struct afb_event event, struct json_object *object) +static inline int afb_event_x1_broadcast(struct afb_event_x1 event, struct json_object *object) { return event.itf->broadcast(event.closure, object); } -/* +/** + * @deprecated use bindings version 3 + * * Pushes the 'event' with the data 'object' to its observers. * 'object' can be NULL. * @@ -71,35 +70,41 @@ static inline int afb_event_broadcast(struct afb_event event, struct json_object * * Returns the count of clients that received the event. */ -static inline int afb_event_push(struct afb_event event, struct json_object *object) +static inline int afb_event_x1_push(struct afb_event_x1 event, struct json_object *object) { return event.itf->push(event.closure, object); } /* OBSOLETE */ -#define afb_event_drop afb_event_unref +#define afb_event_x1_drop afb_event_x1_unref -/* +/** + * @deprecated use bindings version 3 + * * Gets the name associated to the 'event'. */ -static inline const char *afb_event_name(struct afb_event event) +static inline const char *afb_event_x1_name(struct afb_event_x1 event) { return event.itf->name(event.closure); } -/* +/** + * @deprecated use bindings version 3 + * * Decreases the count of reference to 'event' and * destroys the event when the reference count falls to zero. */ -static inline void afb_event_unref(struct afb_event event) +static inline void afb_event_x1_unref(struct afb_event_x1 event) { event.itf->unref(event.closure); } -/* +/** + * @deprecated use bindings version 3 + * * Increases the count of reference to 'event' */ -static inline void afb_event_addref(struct afb_event event) +static inline void afb_event_x1_addref(struct afb_event_x1 event) { event.itf->addref(event.closure); } diff --git a/include/afb/afb-eventid-itf.h b/include/afb/afb-event-x2-itf.h index 0af36581..ecc42c79 100644 --- a/include/afb/afb-eventid-itf.h +++ b/include/afb/afb-event-x2-itf.h @@ -17,31 +17,41 @@ #pragma once -struct json_object; -struct afb_eventid; -struct afb_eventid_itf; +struct afb_event_x2; +struct afb_event_x2_itf; -/* - * Interface for handling eventid. - * It records the functions to be called for the eventid. +/** + * Interface for handling event_x2. + * + * It records the functions to be called for the event_x2. + * * Don't use this structure directly. */ -struct afb_eventid_itf +struct afb_event_x2_itf { /* CAUTION: respect the order, add at the end */ - int (*broadcast)(struct afb_eventid *eventid, struct json_object *obj); - int (*push)(struct afb_eventid *eventid, struct json_object *obj); - void (*unref)(struct afb_eventid *eventid); /* aka drop */ - const char *(*name)(struct afb_eventid *eventid); - struct afb_eventid *(*addref)(struct afb_eventid *eventid); + /** broadcast the event */ + int (*broadcast)(struct afb_event_x2 *event, struct json_object *obj); + + /** push the event to its subscribers */ + int (*push)(struct afb_event_x2 *event, struct json_object *obj); + + /** unreference the event */ + void (*unref)(struct afb_event_x2 *event); /* aka drop */ + + /** get the event name */ + const char *(*name)(struct afb_event_x2 *event); + + /** rereference the event */ + struct afb_event_x2 *(*addref)(struct afb_event_x2 *event); }; -/* - * Describes the eventid +/** + * Describes the event_x2 */ -struct afb_eventid +struct afb_event_x2 { - const struct afb_eventid_itf *itf; /* the interface to use */ + const struct afb_event_x2_itf *itf; /**< the interface functions to use */ }; diff --git a/include/afb/afb-event-x2.h b/include/afb/afb-event-x2.h new file mode 100644 index 00000000..f0a27877 --- /dev/null +++ b/include/afb/afb-event-x2.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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 "afb-event-x2-itf.h" + +/** + * Checks whether the 'event' is valid or not. + * + * @param event the event to check + * + * @return 0 if not valid or 1 if valid. + */ +static inline int afb_event_x2_is_valid(struct afb_event_x2 *event) +{ + return !!event; +} + +/** + * Broadcasts widely an event of 'event' with the data 'object'. + * 'object' can be NULL. + * + * For convenience, the function calls 'json_object_put' for 'object'. + * Thus, in the case where 'object' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * @param event the event to broadcast + * @param object the companion object to associate to the broadcasted event (can be NULL) + * + * @return the count of clients that received the event. + */ +static inline int afb_event_x2_broadcast( + struct afb_event_x2 *event, + struct json_object *object) +{ + return event->itf->broadcast(event, object); +} + +/** + * Pushes an event of 'event' with the data 'object' to its observers. + * 'object' can be NULL. + * + * For convenience, the function calls 'json_object_put' for 'object'. + * Thus, in the case where 'object' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * @param event the event to push + * @param object the companion object to associate to the pushed event (can be NULL) + * + * @return the count of clients that received the event. + */ +static inline int afb_event_x2_push( + struct afb_event_x2 *event, + struct json_object *object) +{ + return event->itf->push(event, object); +} + +/** + * Gets the name associated to 'event'. + * + * @param event the event whose name is requested + * + * @return the name of the event + * + * The returned name can be used until call to 'afb_event_x2_unref'. + * It shouldn't be freed. + */ +static inline const char *afb_event_x2_name(struct afb_event_x2 *event) +{ + return event->itf->name(event); +} + +/** + * Decrease the count of references to 'event'. + * Call this function when the evenid is no more used. + * It destroys the event_x2 when the reference count falls to zero. + * + * @param event the event + */ +static inline void afb_event_x2_unref(struct afb_event_x2 *event) +{ + event->itf->unref(event); +} + +/** + * Increases the count of references to 'event' + * + * @param event the event + * + * @return the event + */ +static inline struct afb_event_x2 *afb_event_x2_addref( + struct afb_event_x2 *event) +{ + return event->itf->addref(event); +} + diff --git a/include/afb/afb-eventid.h b/include/afb/afb-eventid.h deleted file mode 100644 index 69d82a75..00000000 --- a/include/afb/afb-eventid.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2016, 2017, 2018 "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 "afb-eventid-itf.h" - -/* - * Broadcasts widely an event of 'eventid' with the data 'object'. - * 'object' can be NULL. - * - * For convenience, the function calls 'json_object_put' for 'object'. - * Thus, in the case where 'object' should remain available after - * the function returns, the function 'json_object_get' shall be used. - * - * Returns the count of clients that received the event. - */ -static inline int afb_eventid_broadcast( - struct afb_eventid *eventid, - struct json_object *object) -{ - return eventid->itf->broadcast(eventid, object); -} - -/* - * Pushes an event of 'eventid' with the data 'object' to its observers. - * 'object' can be NULL. - * - * For convenience, the function calls 'json_object_put' for 'object'. - * Thus, in the case where 'object' should remain available after - * the function returns, the function 'json_object_get' shall be used. - * - * Returns the count of clients that received the event. - */ -static inline int afb_eventid_push( - struct afb_eventid *eventid, - struct json_object *object) -{ - return eventid->itf->push(eventid, object); -} - -/* - * Gets the name associated to 'eventid'. - * The returned name can be used until call to 'afb_eventid_unref'. - */ -static inline const char *afb_eventid_name(struct afb_eventid *eventid) -{ - return eventid->itf->name(eventid); -} - -/* - * Decrease the count of references to 'eventid'. - * Call this function when the evenid is no more used. - * It destroys the eventid when the reference count falls to zero. - */ -static inline void afb_eventid_unref(struct afb_eventid *eventid) -{ - eventid->itf->unref(eventid); -} - -/* - * Increases the count of references to 'eventid' - */ -static inline struct afb_eventid *afb_eventid_addref( - struct afb_eventid *eventid) -{ - return eventid->itf->addref(eventid); -} - diff --git a/include/afb/afb-req-v1.h b/include/afb/afb-req-v1.h index f1bcd47d..40fb3b85 100644 --- a/include/afb/afb-req-v1.h +++ b/include/afb/afb-req-v1.h @@ -18,34 +18,38 @@ #pragma once #include <stdlib.h> -#include "afb-req.h" +#include "afb-req-x1.h" -/* +/** + * @deprecated use bindings version 3 + * * Stores 'req' on heap for asynchrnous use. * Returns a pointer to the stored 'req' or NULL on memory depletion. * The count of reference to 'req' is incremented on success * (see afb_req_addref). */ -static inline struct afb_req *afb_req_store_v1(struct afb_req req) +static inline struct afb_req_x1 *afb_req_x1_store_v1(struct afb_req_x1 req) { - struct afb_req *result = (struct afb_req*)malloc(sizeof *result); + struct afb_req_x1 *result = (struct afb_req_x1*)malloc(sizeof *result); if (result) { *result = req; - afb_req_addref(req); + afb_req_x1_addref(req); } return result; } -/* +/** + * @deprecated use bindings version 3 + * * Retrieves the afb_req stored at 'req' and frees the memory. * Returns the stored request. * The count of reference is UNCHANGED, thus, normally, the * function 'afb_req_unref' should be called on the result * after that the asynchronous reply if sent. */ -static inline struct afb_req afb_req_unstore_v1(struct afb_req *req) +static inline struct afb_req_x1 afb_req_unstore_x1_v1(struct afb_req_x1 *req) { - struct afb_req result = *req; + struct afb_req_x1 result = *req; free(req); return result; } diff --git a/include/afb/afb-req-v2.h b/include/afb/afb-req-v2.h index 34cbbdaa..f7901908 100644 --- a/include/afb/afb-req-v2.h +++ b/include/afb/afb-req-v2.h @@ -17,16 +17,18 @@ #pragma once -#include "afb-req.h" +#include "afb-req-x1.h" -/* +/** + * @deprecated use bindings version 3 + * * Stores 'req' on heap for asynchrnous use. * Returns a handler to the stored 'req' or NULL on memory depletion. * The count of reference to 'req' is incremented on success * (see afb_req_addref). */ -static inline struct afb_stored_req *afb_req_store_v2(struct afb_req req) +static inline struct afb_stored_req *afb_req_x1_store_v2(struct afb_req_x1 req) { - return req.itf->store(req.closure); + return req.itf->legacy_store_req(req.closure); } diff --git a/include/afb/afb-req-itf.h b/include/afb/afb-req-x1-itf.h index 2dd42d2e..dce936d1 100644 --- a/include/afb/afb-req-itf.h +++ b/include/afb/afb-req-x1-itf.h @@ -17,14 +17,16 @@ #pragma once -#include "afb-request-itf.h" +#include "afb-req-x2-itf.h" -/* - * Describes the request by bindings from afb-daemon +/** + * @deprecated use bindings version 3 + * + * Describes the request to bindings version 1 and 2 */ -struct afb_req +struct afb_req_x1 { - const struct afb_request_itf *itf; /* the interface to use */ - struct afb_request *closure; /* the closure argument for functions of 'itf' */ + const struct afb_req_x2_itf *itf; /**< the interface to use */ + struct afb_req_x2 *closure; /**< the closure argument for functions of 'itf' */ }; diff --git a/include/afb/afb-req.h b/include/afb/afb-req-x1.h index 77153ef1..cea17d0c 100644 --- a/include/afb/afb-req.h +++ b/include/afb/afb-req-x1.h @@ -17,28 +17,34 @@ #pragma once -#include "afb-req-itf.h" -#include "afb-event.h" +#include "afb-req-x1-itf.h" +#include "afb-event-x1.h" -/* +/** + * @deprecated use bindings version 3 + * * Converts the 'req' to an afb_request. */ -static inline struct afb_request *afb_req_to_request(struct afb_req req) +static inline struct afb_req_x2 *afb_req_x1_to_req_x2(struct afb_req_x1 req) { return req.closure; } -/* +/** + * @deprecated use bindings version 3 + * * Checks whether the request 'req' is valid or not. * * Returns 0 if not valid or 1 if valid. */ -static inline int afb_req_is_valid(struct afb_req req) +static inline int afb_req_x1_is_valid(struct afb_req_x1 req) { return !!req.itf; } -/* +/** + * @deprecated use bindings version 3 + * * Gets from the request 'req' the argument of 'name'. * Returns a PLAIN structure of type 'struct afb_arg'. * When the argument of 'name' is not found, all fields of result are set to NULL. @@ -50,157 +56,141 @@ static inline int afb_req_is_valid(struct afb_req req) * an HTTP POST of Content-Type "application/json". In that case, the * argument of name "" receives the value of the body of the HTTP request. */ -static inline struct afb_arg afb_req_get(struct afb_req req, const char *name) +static inline struct afb_arg afb_req_x1_get(struct afb_req_x1 req, const char *name) { return req.itf->get(req.closure, name); } -/* +/** + * @deprecated use bindings version 3 + * * Gets from the request 'req' the string value of the argument of 'name'. * Returns NULL if when there is no argument of 'name'. * Returns the value of the argument of 'name' otherwise. * * Shortcut for: afb_req_get(req, name).value */ -static inline const char *afb_req_value(struct afb_req req, const char *name) +static inline const char *afb_req_x1_value(struct afb_req_x1 req, const char *name) { - return afb_req_get(req, name).value; + return afb_req_x1_get(req, name).value; } -/* +/** + * @deprecated use bindings version 3 + * * Gets from the request 'req' the path for file attached to the argument of 'name'. * Returns NULL if when there is no argument of 'name' or when there is no file. * Returns the path of the argument of 'name' otherwise. * * Shortcut for: afb_req_get(req, name).path */ -static inline const char *afb_req_path(struct afb_req req, const char *name) +static inline const char *afb_req_x1_path(struct afb_req_x1 req, const char *name) { - return afb_req_get(req, name).path; + return afb_req_x1_get(req, name).path; } -/* +/** + * @deprecated use bindings version 3 + * * Gets from the request 'req' the json object hashing the arguments. * The returned object must not be released using 'json_object_put'. */ -static inline struct json_object *afb_req_json(struct afb_req req) +static inline struct json_object *afb_req_x1_json(struct afb_req_x1 req) { return req.itf->json(req.closure); } -/* - * Sends a reply of kind success to the request 'req'. - * The status of the reply is automatically set to "success". +/** + * @deprecated use bindings version 3 + * + * Sends a reply to the request 'req'. + * The status of the reply is set to 'error' (that must be NULL on success). * Its send the object 'obj' (can be NULL) with an - * informationnal comment 'info (can also be NULL). + * informational comment 'info (can also be NULL). * * For convenience, the function calls 'json_object_put' for 'obj'. * Thus, in the case where 'obj' should remain available after * the function returns, the function 'json_object_get' shall be used. */ -static inline void afb_req_success(struct afb_req req, struct json_object *obj, const char *info) +static inline void afb_req_x1_reply(struct afb_req_x1 req, struct json_object *obj, const char *error, const char *info) { - req.itf->success(req.closure, obj, info); + req.itf->reply(req.closure, obj, error, info); } -/* - * Same as 'afb_req_success' but the 'info' is a formatting +/** + * @deprecated use bindings version 3 + * + * Same as 'afb_req_x1_reply' but the 'info' is a formatting * string followed by arguments. * * For convenience, the function calls 'json_object_put' for 'obj'. * Thus, in the case where 'obj' should remain available after * the function returns, the function 'json_object_get' shall be used. */ -static inline void afb_req_success_f(struct afb_req req, struct json_object *obj, const char *info, ...) __attribute__((format(printf, 3, 4))); -static inline void afb_req_success_f(struct afb_req req, struct json_object *obj, const char *info, ...) +static inline void afb_req_x1_reply_f(struct afb_req_x1 req, struct json_object *obj, const char *error, const char *info, ...) __attribute__((format(printf, 4, 5))); +static inline void afb_req_x1_reply_f(struct afb_req_x1 req, struct json_object *obj, const char *error, const char *info, ...) { va_list args; va_start(args, info); - req.itf->vsuccess(req.closure, obj, info, args); + req.itf->vreply(req.closure, obj, error, info, args); va_end(args); } -/* - * Same as 'afb_req_success_f' but the arguments to the format 'info' +/** + * @deprecated use bindings version 3 + * + * Same as 'afb_req_x1_reply_f' but the arguments to the format 'info' * are given as a variable argument list instance. * * For convenience, the function calls 'json_object_put' for 'obj'. * Thus, in the case where 'obj' should remain available after * the function returns, the function 'json_object_get' shall be used. */ -static inline void afb_req_success_v(struct afb_req req, struct json_object *obj, const char *info, va_list args) +static inline void afb_req_x1_reply_v(struct afb_req_x1 req, struct json_object *obj, const char *error, const char *info, va_list args) { - req.itf->vsuccess(req.closure, obj, info, args); + req.itf->vreply(req.closure, obj, error, info, args); } -/* - * Sends a reply of kind failure to the request 'req'. - * The status of the reply is set to 'status' and an - * informationnal comment 'info' (can also be NULL) can be added. +/** + * @deprecated use bindings version 3 * - * Note that calling afb_req_fail("success", info) is equivalent - * to call afb_req_success(NULL, info). Thus even if possible it - * is strongly recommanded to NEVER use "success" for status. - */ -static inline void afb_req_fail(struct afb_req req, const char *status, const char *info) -{ - req.itf->fail(req.closure, status, info); -} - -/* - * Same as 'afb_req_fail' but the 'info' is a formatting - * string followed by arguments. - */ -static inline void afb_req_fail_f(struct afb_req req, const char *status, const char *info, ...) __attribute__((format(printf, 3, 4))); -static inline void afb_req_fail_f(struct afb_req req, const char *status, const char *info, ...) -{ - va_list args; - va_start(args, info); - req.itf->vfail(req.closure, status, info, args); - va_end(args); -} - -/* - * Same as 'afb_req_fail_f' but the arguments to the format 'info' - * are given as a variable argument list instance. - */ -static inline void afb_req_fail_v(struct afb_req req, const char *status, const char *info, va_list args) -{ - req.itf->vfail(req.closure, status, info, args); -} - -/* * Gets the pointer stored by the binding for the session of 'req'. * When the binding has not yet recorded a pointer, NULL is returned. */ -static inline void *afb_req_context_get(struct afb_req req) +static inline void *afb_req_x1_context_get(struct afb_req_x1 req) { - return req.itf->context_get(req.closure); + return req.itf->context_make(req.closure, 0, 0, 0, 0); } -/* +/** + * @deprecated use bindings version 3 + * * Stores for the binding the pointer 'context' to the session of 'req'. * The function 'free_context' will be called when the session is closed * or if binding stores an other pointer. */ -static inline void afb_req_context_set(struct afb_req req, void *context, void (*free_context)(void*)) +static inline void afb_req_x1_context_set(struct afb_req_x1 req, void *context, void (*free_context)(void*)) { - req.itf->context_set(req.closure, context, free_context); + req.itf->context_make(req.closure, 1, 0, free_context, context); } -/* +/** + * @deprecated use bindings version 3 + * * Gets the pointer stored by the binding for the session of 'req'. * If the stored pointer is NULL, indicating that no pointer was * already stored, afb_req_context creates a new context by calling * the function 'create_context' and stores it with the freeing function * 'free_context'. */ -static inline void *afb_req_context(struct afb_req req, void *(*create_context)(), void (*free_context)(void*)) +static inline void *afb_req_x1_context(struct afb_req_x1 req, void *(*create_context)(), void (*free_context)(void*)) { return req.itf->context_make(req.closure, 0, (void *(*)(void*))(void*)create_context, free_context, 0); } -/* +/** + * @deprecated use bindings version 3 + * * Gets the pointer stored by the binding for the session of 'request'. * If no previous pointer is stored or if 'replace' is not zero, a new value * is generated using the function 'create_context' called with the 'closure'. @@ -210,83 +200,99 @@ static inline void *afb_req_context(struct afb_req req, void *(*create_context)( * it is not more used. * This function is atomic: it ensures that 2 threads will not race together. */ -static inline void *afb_req_context_make(struct afb_req req, int replace, void *(*create_context)(void *closure), void (*free_context)(void*), void *closure) +static inline void *afb_req_x1_context_make(struct afb_req_x1 req, int replace, void *(*create_context)(void *closure), void (*free_context)(void*), void *closure) { return req.itf->context_make(req.closure, replace, create_context, free_context, closure); } -/* +/** + * @deprecated use bindings version 3 + * * Frees the pointer stored by the binding for the session of 'req' * and sets it to NULL. * * Shortcut for: afb_req_context_set(req, NULL, NULL) */ -static inline void afb_req_context_clear(struct afb_req req) +static inline void afb_req_x1_context_clear(struct afb_req_x1 req) { - afb_req_context_set(req, 0, 0); + req.itf->context_make(req.closure, 1, 0, 0, 0); } -/* +/** + * @deprecated use bindings version 3 + * * Adds one to the count of references of 'req'. * This function MUST be called by asynchronous implementations * of verbs if no reply was sent before returning. */ -static inline void afb_req_addref(struct afb_req req) +static inline void afb_req_x1_addref(struct afb_req_x1 req) { req.itf->addref(req.closure); } -/* +/** + * @deprecated use bindings version 3 + * * Substracts one to the count of references of 'req'. * This function MUST be called by asynchronous implementations * of verbs after sending the asynchronous reply. */ -static inline void afb_req_unref(struct afb_req req) +static inline void afb_req_x1_unref(struct afb_req_x1 req) { req.itf->unref(req.closure); } -/* +/** + * @deprecated use bindings version 3 + * * Closes the session associated with 'req' * and delete all associated contexts. */ -static inline void afb_req_session_close(struct afb_req req) +static inline void afb_req_x1_session_close(struct afb_req_x1 req) { req.itf->session_close(req.closure); } -/* +/** + * @deprecated use bindings version 3 + * * Sets the level of assurance of the session of 'req' * to 'level'. The effect of this function is subject of * security policies. * Returns 1 on success or 0 if failed. */ -static inline int afb_req_session_set_LOA(struct afb_req req, unsigned level) +static inline int afb_req_x1_session_set_LOA(struct afb_req_x1 req, unsigned level) { - return req.itf->session_set_LOA(req.closure, level); + return 1 + req.itf->session_set_LOA(req.closure, level); } -/* +/** + * @deprecated use bindings version 3 + * * Establishes for the client link identified by 'req' a subscription * to the 'event'. * Returns 0 in case of successful subscription or -1 in case of error. */ -static inline int afb_req_subscribe(struct afb_req req, struct afb_event event) +static inline int afb_req_x1_subscribe(struct afb_req_x1 req, struct afb_event_x1 event) { - return req.itf->subscribe(req.closure, event); + return req.itf->legacy_subscribe_event_x1(req.closure, event); } -/* +/** + * @deprecated use bindings version 3 + * * Revokes the subscription established to the 'event' for the client * link identified by 'req'. * Returns 0 in case of successful subscription or -1 in case of error. */ -static inline int afb_req_unsubscribe(struct afb_req req, struct afb_event event) +static inline int afb_req_x1_unsubscribe(struct afb_req_x1 req, struct afb_event_x1 event) { - return req.itf->unsubscribe(req.closure, event); + return req.itf->legacy_unsubscribe_event_x1(req.closure, event); } -/* +/** + * @deprecated use bindings version 3 + * * Makes a call to the method of name 'api' / 'verb' with the object 'args'. * This call is made in the context of the request 'req'. * On completion, the function 'callback' is invoked with the @@ -303,12 +309,14 @@ static inline int afb_req_unsubscribe(struct afb_req req, struct afb_event event * - 'afb_req_subcall_req' that is convenient to keep request alive automatically. * - 'afb_req_subcall_sync' the synchronous version */ -static inline void afb_req_subcall(struct afb_req req, const char *api, const char *verb, struct json_object *args, void (*callback)(void *closure, int iserror, struct json_object *result), void *closure) +static inline void afb_req_x1_subcall(struct afb_req_x1 req, const char *api, const char *verb, struct json_object *args, void (*callback)(void *closure, int iserror, struct json_object *result), void *closure) { - req.itf->subcall(req.closure, api, verb, args, callback, closure); + req.itf->legacy_subcall(req.closure, api, verb, args, callback, closure); } -/* +/** + * @deprecated use bindings version 3 + * * Makes a call to the method of name 'api' / 'verb' with the object 'args'. * This call is made in the context of the request 'req'. * On completion, the function 'callback' is invoked with the @@ -326,12 +334,14 @@ static inline void afb_req_subcall(struct afb_req req, const char *api, const ch * - 'afb_req_subcall' that doesn't keep request alive automatically. * - 'afb_req_subcall_sync' the synchronous version */ -static inline void afb_req_subcall_req(struct afb_req req, const char *api, const char *verb, struct json_object *args, void (*callback)(void *closure, int iserror, struct json_object *result, struct afb_req req), void *closure) +static inline void afb_req_x1_subcall_req(struct afb_req_x1 req, const char *api, const char *verb, struct json_object *args, void (*callback)(void *closure, int iserror, struct json_object *result, struct afb_req_x1 req), void *closure) { - req.itf->subcall_req(req.closure, api, verb, args, callback, closure); + req.itf->legacy_subcall_req(req.closure, api, verb, args, callback, closure); } -/* +/** + * @deprecated use bindings version 3 + * * Makes a call to the method of name 'api' / 'verb' with the object 'args'. * This call is made in the context of the request 'req'. * This call is synchronous, it waits untill completion of the request. @@ -347,12 +357,14 @@ static inline void afb_req_subcall_req(struct afb_req req, const char *api, cons * - 'afb_req_subcall_req' that is convenient to keep request alive automatically. * - 'afb_req_subcall' that doesn't keep request alive automatically. */ -static inline int afb_req_subcall_sync(struct afb_req req, const char *api, const char *verb, struct json_object *args, struct json_object **result) +static inline int afb_req_x1_subcall_sync(struct afb_req_x1 req, const char *api, const char *verb, struct json_object *args, struct json_object **result) { - return req.itf->subcallsync(req.closure, api, verb, args, result); + return req.itf->legacy_subcallsync(req.closure, api, verb, args, result); } -/* +/** + * @deprecated use bindings version 3 + * * Send associated to 'req' a message described by 'fmt' and following parameters * to the journal for the verbosity 'level'. * @@ -369,8 +381,8 @@ static inline int afb_req_subcall_sync(struct afb_req req, const char *api, cons * INFO 6 Informational * DEBUG 7 Debug-level messages */ -static inline void afb_req_verbose(struct afb_req req, int level, const char *file, int line, const char * func, const char *fmt, ...) __attribute__((format(printf, 6, 7))); -static inline void afb_req_verbose(struct afb_req req, int level, const char *file, int line, const char * func, const char *fmt, ...) +static inline void afb_req_x1_verbose(struct afb_req_x1 req, int level, const char *file, int line, const char * func, const char *fmt, ...) __attribute__((format(printf, 6, 7))); +static inline void afb_req_x1_verbose(struct afb_req_x1 req, int level, const char *file, int line, const char * func, const char *fmt, ...) { va_list args; va_start(args, fmt); @@ -378,25 +390,22 @@ static inline void afb_req_verbose(struct afb_req req, int level, const char *fi va_end(args); } -/* macro for setting file, line and function automatically */ -# if !defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DETAILS) -#define AFB_REQ_VERBOSE(req,level,...) afb_req_verbose(req,level,__FILE__,__LINE__,__func__,__VA_ARGS__) -#else -#define AFB_REQ_VERBOSE(req,level,...) afb_req_verbose(req,level,NULL,0,NULL,__VA_ARGS__) -#endif - -/* +/** + * @deprecated use bindings version 3 + * * Check whether the 'permission' is granted or not to the client * identified by 'req'. * * Returns 1 if the permission is granted or 0 otherwise. */ -static inline int afb_req_has_permission(struct afb_req req, const char *permission) +static inline int afb_req_x1_has_permission(struct afb_req_x1 req, const char *permission) { return req.itf->has_permission(req.closure, permission); } -/* +/** + * @deprecated use bindings version 3 + * * Get the application identifier of the client application for the * request 'req'. * @@ -405,19 +414,40 @@ static inline int afb_req_has_permission(struct afb_req req, const char *permiss * * The returned value if not NULL must be freed by the caller */ -static inline char *afb_req_get_application_id(struct afb_req req) +static inline char *afb_req_x1_get_application_id(struct afb_req_x1 req) { return req.itf->get_application_id(req.closure); } -/* +/** + * @deprecated use bindings version 3 + * * Get the user identifier (UID) of the client application for the * request 'req'. * * Returns -1 when the application can not be identified. */ -static inline int afb_req_get_uid(struct afb_req req) +static inline int afb_req_x1_get_uid(struct afb_req_x1 req) { return req.itf->get_uid(req.closure); } +/** + * @deprecated use bindings version 3 + * + * Get informations about the client of the + * request 'req'. + * + * Returns an object with client informations: + * { + * "pid": int, "uid": int, "gid": int, + * "smack": string, "appid": string, + * "uuid": string, "LOA": int + * } + */ +static inline struct json_object *afb_req_x1_get_client_info(struct afb_req_x1 req) +{ + return req.itf->get_client_info(req.closure); +} + + diff --git a/include/afb/afb-req-x2-itf.h b/include/afb/afb-req-x2-itf.h new file mode 100644 index 00000000..9de7a214 --- /dev/null +++ b/include/afb/afb-req-x2-itf.h @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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 + +/* defined here */ +struct afb_req_x2; +struct afb_req_x2_itf; + +/* referenced here */ +#include "afb-arg.h" +struct afb_req_x1; +struct afb_event_x1; +struct afb_event_x2; +struct afb_api_x3; +struct afb_stored_req; + +/** + * structure for the request + */ +struct afb_req_x2 +{ + /** + * interface for the request + */ + const struct afb_req_x2_itf *itf; + + /** + * current api (if any) + */ + struct afb_api_x3 *api; + + /** + * closure associated with the callback processing the verb of the request + * as given at its declaration + */ + void *vcbdata; + + /** + * the name of the called api + */ + const char *called_api; + + /** + * the name of the called verb + */ + const char *called_verb; +}; + +/** + * subcall modes + * + * When making subcalls, it is now possible to explicitely set the subcall + * mode to a combination of the following mode using binary OR. + * + * In particular, the following combination of modes are to be known: + * + * - for **subcall** having a similar behaviour to the subcalls of bindings + * version 1 and 2: afb_req_x2_subcall_pass_events|afb_req_x2_subcall_on_behalf + * - for **subcall** having the behaviour of the **call**: + * afb_req_x2_subcall_catch_events|afb_req_x2_subcall_api_session + * + * Be aware that if none of mode afb_req_x2_subcall_catch_events or + * afb_req_x2_subcall_pass_events is set, subscrption to events will be ignored. + */ +enum afb_req_x2_subcall_flags +{ + /** + * the calling API wants to receive the events from subscription + */ + afb_req_x2_subcall_catch_events = 1, + + /** + * the original request will receive the events from subscription + */ + afb_req_x2_subcall_pass_events = 2, + + /** + * the calling API wants to use the credentials of the original request + */ + afb_req_x2_subcall_on_behalf = 4, + + /** + * the calling API wants to use its session instead of the one of the + * original request + */ + afb_req_x2_subcall_api_session = 8, +}; + +/** + * Interface for handling requests. + * + * It records the functions to be called for the request. + * Don't use this structure directly, Use the helper functions instead. + */ +struct afb_req_x2_itf +{ + /* CAUTION: respect the order, add at the end */ + + /** get the json */ + struct json_object *(*json)( + struct afb_req_x2 *req); + + /** get an argument */ + struct afb_arg (*get)( + struct afb_req_x2 *req, + const char *name); + + /** reply a success @deprecated use @ref reply */ + void (*legacy_success)( + struct afb_req_x2 *req, + struct json_object *obj, + const char *info); + + /** reply a failure @deprecated use @ref reply */ + void (*legacy_fail)( + struct afb_req_x2 *req, + const char *status, + const char *info); + + /** reply a success @deprecated use @ref vreply */ + void (*legacy_vsuccess)( + struct afb_req_x2 *req, + struct json_object *obj, + const char *fmt, + va_list args); + + /** reply a failure @deprecated use @ref vreply */ + void (*legacy_vfail)( + struct afb_req_x2 *req, + const char *status, + const char *fmt, + va_list args); + + /** get a client context @deprecated use @ref context_make */ + void *(*legacy_context_get)( + struct afb_req_x2 *req); + + /** set a client context @deprecated use @ref context_make */ + void (*legacy_context_set)( + struct afb_req_x2 *req, + void *value, + void (*free_value)(void*)); + + /** increase reference count of the request */ + struct afb_req_x2 *(*addref)( + struct afb_req_x2 *req); + + /** decrease reference count of the request */ + void (*unref)( + struct afb_req_x2 *req); + + /** close the client session related to the api of the request */ + void (*session_close)( + struct afb_req_x2 *req); + + /** set the levele of assurancy related to the api of the request */ + int (*session_set_LOA)( + struct afb_req_x2 *req, + unsigned level); + + /** make subscription of the client of the request to the event @deprecated use @ref subscribe_event_x2 */ + int (*legacy_subscribe_event_x1)( + struct afb_req_x2 *req, + struct afb_event_x1 event); + + /** remove subscription of the client of the request to the event @deprecated use @ref unsubscribe_event_x2 */ + int (*legacy_unsubscribe_event_x1)( + struct afb_req_x2 *req, + struct afb_event_x1 event); + + /** asynchronous subcall @deprecated use @ref subcall */ + void (*legacy_subcall)( + struct afb_req_x2 *req, + const char *api, + const char *verb, + struct json_object *args, + void (*callback)(void*, int, struct json_object*), + void *cb_closure); + + /** synchronous subcall @deprecated use @ref subcallsync */ + int (*legacy_subcallsync)( + struct afb_req_x2 *req, + const char *api, + const char *verb, + struct json_object *args, + struct json_object **result); + + /** log a message for the request */ + void (*vverbose)( + struct afb_req_x2 *req, + int level, + const char *file, + int line, + const char * func, + const char *fmt, + va_list args); + + /** store the request @deprecated no more needed */ + struct afb_stored_req *(*legacy_store_req)( + struct afb_req_x2 *req); + + /** asynchronous subcall with request @deprecated use @ref subcall */ + void (*legacy_subcall_req)( + struct afb_req_x2 *req, + const char *api, + const char *verb, + struct json_object *args, + void (*callback)(void*, int, struct json_object*, struct afb_req_x1), + void *cb_closure); + + /** store the request @deprecated no more needed */ + int (*has_permission)( + struct afb_req_x2 *req, + const char *permission); + + /** get the application id of the client of the request */ + char *(*get_application_id)( + struct afb_req_x2 *req); + + /** handle client context of the api getting the request */ + void *(*context_make)( + struct afb_req_x2 *req, + int replace, + void *(*create_value)(void *creation_closure), + void (*free_value)(void*), + void *creation_closure); + + /** make subscription of the client of the request to the event */ + int (*subscribe_event_x2)( + struct afb_req_x2 *req, + struct afb_event_x2 *event); + + /** remove subscription of the client of the request to the event */ + int (*unsubscribe_event_x2)( + struct afb_req_x2 *req, + struct afb_event_x2 *event); + + /** asynchronous subcall with request @deprecated use @ref subcall */ + void (*legacy_subcall_request)( + struct afb_req_x2 *req, + const char *api, + const char *verb, + struct json_object *args, + void (*callback)(void*, int, struct json_object*, struct afb_req_x2 *req), + void *cb_closure); + + /** get the user id (unix) of the client of the request */ + int (*get_uid)( + struct afb_req_x2 *req); + + /** reply to the request */ + void (*reply)( + struct afb_req_x2 *req, + struct json_object *obj, + const char *error, + const char *info); + + /** reply to the request with formating of info */ + void (*vreply)( + struct afb_req_x2 *req, + struct json_object *obj, + const char *error, + const char *fmt, + va_list args); + + /** get description of the client of the request */ + struct json_object *(*get_client_info)( + struct afb_req_x2 *req); + + /** asynchronous subcall */ + void (*subcall)( + struct afb_req_x2 *req, + const char *apiname, + const char *verb, + struct json_object *args, + int flags, + void (*callback)(void *closure, struct json_object *object, const char *error, const char * info, struct afb_req_x2 *req), + void *closure); + + /** synchronous subcall */ + int (*subcallsync)( + struct afb_req_x2 *req, + const char *api, + const char *verb, + struct json_object *args, + int flags, + struct json_object **object, + char **error, + char **info); +}; + diff --git a/include/afb/afb-req-x2.h b/include/afb/afb-req-x2.h new file mode 100644 index 00000000..70ffab80 --- /dev/null +++ b/include/afb/afb-req-x2.h @@ -0,0 +1,758 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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 "afb-req-x2-itf.h" +#include "afb-api-x3.h" + +/** + * Checks whether the request 'req' is valid or not. + * + * @param req the request to check + * + * @return 0 if not valid or 1 if valid. + */ +static inline +int afb_req_x2_is_valid( + struct afb_req_x2 *req) +{ + return !!req; +} + +/** + * Retrieves the api that serves the request + * + * @param req the request whose serving api is queried + * + * @return the api serving the request + */ +static inline +struct afb_api_x3 *afb_req_x2_get_api( + struct afb_req_x2 *req) +{ + return req->api; +} + +/** + * Retrieves the callback data of the verb. This callback data is set + * when the verb is created. + * + * @param req whose verb vcbdata is queried + * + * @return the callback data attached to the verb description + */ +static inline +void *afb_req_x2_get_vcbdata( + struct afb_req_x2 *req) +{ + return req->vcbdata; +} + +/** + * Retrieve the name of the called api. + * + * @param req the request + * + * @return the name of the called api + * + * @see afb_api_x3_add_alias + */ +static inline +const char *afb_req_x2_get_called_api( + struct afb_req_x2 *req) +{ + return req->called_api; +} + +/** + * Retrieve the name of the called verb + * + * @param req the request + * + * @return the name of the called verb + */ +static inline +const char *afb_req_x2_get_called_verb( + struct afb_req_x2 *req) +{ + return req->called_verb; +} + +/** + * Is the log message of 'level (as defined for syslog) required for the + * request 'req'? + * + * @param req the request + * @param level the level to check as defined for syslog: + * + * EMERGENCY 0 System is unusable + * ALERT 1 Action must be taken immediately + * CRITICAL 2 Critical conditions + * ERROR 3 Error conditions + * WARNING 4 Warning conditions + * NOTICE 5 Normal but significant condition + * INFO 6 Informational + * DEBUG 7 Debug-level messages + * + * @return 0 if not required or a value not null if required + * + * @see syslog + */ +static inline +int afb_req_x2_wants_log_level( + struct afb_req_x2 *req, + int level) +{ + return afb_api_x3_wants_log_level(afb_req_x2_get_api(req), level); +} + +/** + * Gets from the request 'req' the argument of 'name'. + * + * Returns a PLAIN structure of type 'struct afb_arg'. + * + * When the argument of 'name' is not found, all fields of result are set to NULL. + * + * When the argument of 'name' is found, the fields are filled, + * in particular, the field 'result.name' is set to 'name'. + * + * There is a special name value: the empty string. + * The argument of name "" is defined only if the request was made using + * an HTTP POST of Content-Type "application/json". In that case, the + * argument of name "" receives the value of the body of the HTTP request. + * + * @param req the request + * @param name the name of the argument to get + * + * @return a structure describing the retrieved argument for the request + * + * @see afb_req_x2_value + * @see afb_req_x2_path + */ +static inline +struct afb_arg afb_req_x2_get( + struct afb_req_x2 *req, + const char *name) +{ + return req->itf->get(req, name); +} + +/** + * Gets from the request 'req' the string value of the argument of 'name'. + * Returns NULL if when there is no argument of 'name'. + * Returns the value of the argument of 'name' otherwise. + * + * Shortcut for: afb_req_x2_get(req, name).value + * + * @param req the request + * @param name the name of the argument's value to get + * + * @return the value as a string or NULL + * + * @see afb_req_x2_get + * @see afb_req_x2_path + */ +static inline +const char *afb_req_x2_value( + struct afb_req_x2 *req, + const char *name) +{ + return afb_req_x2_get(req, name).value; +} + +/** + * Gets from the request 'req' the path for file attached to the argument of 'name'. + * Returns NULL if when there is no argument of 'name' or when there is no file. + * Returns the path of the argument of 'name' otherwise. + * + * Shortcut for: afb_req_x2_get(req, name).path + * + * @param req the request + * @param name the name of the argument's path to get + * + * @return the path if any or NULL + * + * @see afb_req_x2_get + * @see afb_req_x2_value + */ +static inline +const char *afb_req_x2_path( + struct afb_req_x2 *req, + const char *name) +{ + return afb_req_x2_get(req, name).path; +} + +/** + * Gets from the request 'req' the json object hashing the arguments. + * + * The returned object must not be released using 'json_object_put'. + * + * @param req the request + * + * @return the JSON object of the query + * + * @see afb_req_x2_get + * @see afb_req_x2_value + * @see afb_req_x2_path + */ +static inline +struct json_object *afb_req_x2_json( + struct afb_req_x2 *req) +{ + return req->itf->json(req); +} + +/** + * Sends a reply to the request 'req'. + * + * The status of the reply is set to 'error' (that must be NULL on success). + * Its send the object 'obj' (can be NULL) with an + * informational comment 'info (can also be NULL). + * + * For convenience, the function calls 'json_object_put' for 'obj'. + * Thus, in the case where 'obj' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * @param req the request + * @param obj the replied object or NULL + * @param error the error message if it is a reply error or NULL + * @param info an informative text or NULL + * + * @see afb_req_x2_reply_v + * @see afb_req_x2_reply_f + */ +static inline +void afb_req_x2_reply( + struct afb_req_x2 *req, + struct json_object *obj, + const char *error, + const char *info) +{ + req->itf->reply(req, obj, error, info); +} + +/** + * Same as 'afb_req_x2_reply_f' but the arguments to the format 'info' + * are given as a variable argument list instance. + * + * For convenience, the function calls 'json_object_put' for 'obj'. + * Thus, in the case where 'obj' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * @param req the request + * @param obj the replied object or NULL + * @param error the error message if it is a reply error or NULL + * @param info an informative text containing a format as for vprintf + * @param args the va_list of arguments to the format as for vprintf + * + * @see afb_req_x2_reply + * @see afb_req_x2_reply_f + * @see vprintf + */ +static inline +void afb_req_x2_reply_v( + struct afb_req_x2 *req, + struct json_object *obj, + const char *error, + const char *info, + va_list args) +{ + req->itf->vreply(req, obj, error, info, args); +} + +/** + * Same as 'afb_req_x2_reply' but the 'info' is a formatting + * string followed by arguments. + * + * For convenience, the function calls 'json_object_put' for 'obj'. + * Thus, in the case where 'obj' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * @param req the request + * @param obj the replied object or NULL + * @param error the error message if it is a reply error or NULL + * @param info an informative text containing a format as for printf + * @param ... the arguments to the format as for printf + * + * @see afb_req_x2_reply + * @see afb_req_x2_reply_v + * @see printf + */ +__attribute__((format(printf, 4, 5))) +static inline +void afb_req_x2_reply_f( + struct afb_req_x2 *req, + struct json_object *obj, + const char *error, + const char *info, + ...) +{ + va_list args; + va_start(args, info); + afb_req_x2_reply_v(req, obj, error, info, args); + va_end(args); +} + +/** + * Manage the pointer stored by the binding for the client session of 'req'. + * + * If no previous pointer is stored or if 'replace' is not zero, a new value + * is generated using the function 'create_context' called with the 'closure'. + * If 'create_context' is NULL the generated value is 'closure'. + * + * When a value is created, the function 'free_context' is recorded and will + * be called (with the created value as argument) to free the created value when + * it is not more used. + * + * This function is atomic: it ensures that 2 threads will not race together. + * + * @param req the request + * @param replace if not zero an existing value is replaced + * @param create_context the creation function or NULL + * @param free_context the destroying function or NULL + * @param closure the closure to the creation function + * + * @return the stored value + */ +static inline +void *afb_req_x2_context( + struct afb_req_x2 *req, + int replace, + void *(*create_context)(void *closure), + void (*free_context)(void*), + void *closure) +{ + return req->itf->context_make(req, replace, create_context, free_context, closure); +} + +/** + * Gets the pointer stored by the binding for the session of 'req'. + * When the binding has not yet recorded a pointer, NULL is returned. + * + * Shortcut for: afb_req_x2_context(req, 0, NULL, NULL, NULL) + * + * @param req the request + * + * @return the previously stored value + */ +static inline +void *afb_req_x2_context_get( + struct afb_req_x2 *req) +{ + return afb_req_x2_context(req, 0, 0, 0, 0); +} + +/** + * Stores for the binding the pointer 'context' to the session of 'req'. + * The function 'free_context' will be called when the session is closed + * or if binding stores an other pointer. + * + * Shortcut for: afb_req_x2_context(req, 1, NULL, free_context, context) + * + * + * @param req the request + * @param context the context value to store + * @param free_context the cleaning function for the stored context (can be NULL) + */ +static inline +void afb_req_x2_context_set( + struct afb_req_x2 *req, + void *context, + void (*free_context)(void*)) +{ + afb_req_x2_context(req, 1, 0, free_context, context); +} + +/** + * Frees the pointer stored by the binding for the session of 'req' + * and sets it to NULL. + * + * Shortcut for: afb_req_x2_context_set(req, NULL, NULL) + * + * @param req the request + */ +static inline +void afb_req_x2_context_clear( + struct afb_req_x2 *req) +{ + afb_req_x2_context(req, 1, 0, 0, 0); +} + +/** + * Increments the count of references of 'req'. + * + * @param req the request + * + * @return returns the request req + */ +static inline +struct afb_req_x2 *afb_req_x2_addref( + struct afb_req_x2 *req) +{ + return req->itf->addref(req); +} + +/** + * Decrement the count of references of 'req'. + * + * @param req the request + */ +static inline +void afb_req_x2_unref( + struct afb_req_x2 *req) +{ + req->itf->unref(req); +} + +/** + * Closes the session associated with 'req' + * and delete all associated contexts. + * + * @param req the request + */ +static inline +void afb_req_x2_session_close( + struct afb_req_x2 *req) +{ + req->itf->session_close(req); +} + +/** + * Sets the level of assurance of the session of 'req' + * to 'level'. The effect of this function is subject of + * security policies. + * + * @param req the request + * @param level of assurance from 0 to 7 + * + * @return 0 on success or -1 if failed. + */ +static inline +int afb_req_x2_session_set_LOA( + struct afb_req_x2 *req, + unsigned level) +{ + return req->itf->session_set_LOA(req, level); +} + +/** + * Establishes for the client link identified by 'req' a subscription + * to the 'event'. + * + * @param req the request + * @param event the event to subscribe + * + * @return 0 in case of successful subscription or -1 in case of error. + */ +static inline +int afb_req_x2_subscribe( + struct afb_req_x2 *req, + struct afb_event_x2 *event) +{ + return req->itf->subscribe_event_x2(req, event); +} + +/** + * Revokes the subscription established to the 'event' for the client + * link identified by 'req'. + * Returns 0 in case of successful subscription or -1 in case of error. + * + * @param req the request + * @param event the event to revoke + * + * @return 0 in case of successful subscription or -1 in case of error. + */ +static inline +int afb_req_x2_unsubscribe( + struct afb_req_x2 *req, + struct afb_event_x2 *event) +{ + return req->itf->unsubscribe_event_x2(req, event); +} + +/** + * @deprecated use @ref afb_req_x2_subcall + * + * Makes a call to the method of name 'api' / 'verb' with the object 'args'. + * This call is made in the context of the request 'req'. + * On completion, the function 'callback' is invoked with the + * 'closure' given at call and two other parameters: 'iserror' and 'result'. + * 'status' is 0 on success or negative when on an error reply. + * 'result' is the json object of the reply, you must not call json_object_put + * on the result. + * + * For convenience, the function calls 'json_object_put' for 'args'. + * Thus, in the case where 'args' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * @param req the request + * @param api the name of the api to call + * @param verb the name of the verb to call + * @param args the arguments of the call as a JSON object + * @param callback the call back that will receive the reply + * @param closure the closure passed back to the callback + * + * @see afb_req_x2_subcall + * @see afb_req_x2_subcall_sync + */ +static inline +void afb_req_x2_subcall_legacy( + struct afb_req_x2 *req, + const char *api, + const char *verb, + struct json_object *args, + void (*callback)(void *closure, int iserror, struct json_object *result, struct afb_req_x2 *req), + void *closure) +{ + req->itf->legacy_subcall_request(req, api, verb, args, callback, closure); +} + +/** + * @deprecated use @ref afb_req_x2_subcall_sync + * + * Makes a call to the method of name 'api' / 'verb' with the object 'args'. + * This call is made in the context of the request 'req'. + * This call is synchronous, it waits untill completion of the request. + * It returns 0 on success or a negative value on error answer. + * The object pointed by 'result' is filled and must be released by the caller + * after its use by calling 'json_object_put'. + * + * For convenience, the function calls 'json_object_put' for 'args'. + * Thus, in the case where 'args' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * @param req the request + * @param api the name of the api to call + * @param verb the name of the verb to call + * @param args the arguments of the call as a JSON object + * @param result the pointer to the JSON object pointer that will receive the result + * + * @return 0 on success or a negative value on error answer. + * + * @see afb_req_x2_subcall + * @see afb_req_x2_subcall_sync + */ +static inline +int afb_req_x2_subcall_sync_legacy( + struct afb_req_x2 *req, + const char *api, + const char *verb, + struct json_object *args, + struct json_object **result) +{ + return req->itf->legacy_subcallsync(req, api, verb, args, result); +} + +/** + * Send associated to 'req' a message described by 'fmt' and following parameters + * to the journal for the verbosity 'level'. + * + * 'file', 'line' and 'func' are indicators of position of the code in source files + * (see macros __FILE__, __LINE__ and __func__). + * + * 'level' is defined by syslog standard: + * EMERGENCY 0 System is unusable + * ALERT 1 Action must be taken immediately + * CRITICAL 2 Critical conditions + * ERROR 3 Error conditions + * WARNING 4 Warning conditions + * NOTICE 5 Normal but significant condition + * INFO 6 Informational + * DEBUG 7 Debug-level messages + * + * @param req the request + * @param level the level of the message + * @param file the source filename that emits the message or NULL + * @param line the line number in the source filename that emits the message + * @param func the name of the function that emits the message or NULL + * @param fmt the message format as for printf + * @param ... the arguments of the printf + * + * @see printf + */ +__attribute__((format(printf, 6, 7))) +static inline +void afb_req_x2_verbose( + struct afb_req_x2 *req, + int level, const char *file, + int line, + const char * func, + const char *fmt, + ...) +{ + va_list args; + va_start(args, fmt); + req->itf->vverbose(req, level, file, line, func, fmt, args); + va_end(args); +} + +/** + * Check whether the 'permission' is granted or not to the client + * identified by 'req'. + * + * @param req the request + * @param permission string to check + * + * @return 1 if the permission is granted or 0 otherwise. + */ +static inline +int afb_req_x2_has_permission( + struct afb_req_x2 *req, + const char *permission) +{ + return req->itf->has_permission(req, permission); +} + +/** + * Get the application identifier of the client application for the + * request 'req'. + * + * Returns the application identifier or NULL when the application + * can not be identified. + * + * The returned value if not NULL must be freed by the caller + * + * @param req the request + * + * @return the string for the application id of the client MUST BE FREED + */ +static inline +char *afb_req_x2_get_application_id( + struct afb_req_x2 *req) +{ + return req->itf->get_application_id(req); +} + +/** + * Get the user identifier (UID) of the client for the + * request 'req'. + * + * @param req the request + * + * @return -1 when the application can not be identified or the unix uid. + * + */ +static inline +int afb_req_x2_get_uid( + struct afb_req_x2 *req) +{ + return req->itf->get_uid(req); +} + +/** + * Get informations about the client of the + * request 'req'. + * + * Returns an object with client informations: + * { + * "pid": int, "uid": int, "gid": int, + * "label": string, "id": string, "user": string, + * "uuid": string, "LOA": int + * } + * + * If some of this information can't be computed, the field of the return + * object will not be set at all. + * + * @param req the request + * + * @return a JSON object that must be freed using @ref json_object_put + */ +static inline +struct json_object *afb_req_x2_get_client_info( + struct afb_req_x2 *req) +{ + return req->itf->get_client_info(req); +} + +/** + * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. + * The result of the call is delivered to the 'callback' function with the 'callback_closure'. + * + * For convenience, the function calls 'json_object_put' for 'args'. + * Thus, in the case where 'args' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * The 'callback' receives 5 arguments: + * 1. 'closure' the user defined closure pointer 'closure', + * 2. 'object' a JSON object returned (can be NULL) + * 3. 'error' a string not NULL in case of error + * 4. 'info' a string handling some info (can be NULL) + * 5. 'req' the req + * + * @param req The request + * @param api The api name of the method to call + * @param verb The verb name of the method to call + * @param args The arguments to pass to the method + * @param flags The bit field of flags for the subcall as defined by @ref afb_req_x2_subcall_flags + * @param callback The to call on completion + * @param closure The closure to pass to the callback + * + * @see also 'afb_req_subcall_sync' + */ +static inline +void afb_req_x2_subcall( + struct afb_req_x2 *req, + const char *api, + const char *verb, + struct json_object *args, + int flags, + void (*callback)(void *closure, struct json_object *object, const char *error, const char * info, struct afb_req_x2 *req), + void *closure) +{ + req->itf->subcall(req, api, verb, args, flags, callback, closure); +} + +/** + * Makes a call to the method of name 'api' / 'verb' with the object 'args'. + * This call is made in the context of the request 'req'. + * This call is synchronous, it waits untill completion of the request. + * It returns 0 on success or a negative value on error answer. + * + * For convenience, the function calls 'json_object_put' for 'args'. + * Thus, in the case where 'args' should remain available after + * the function returns, the function 'json_object_get' shall be used. + * + * See also: + * - 'afb_req_x2_subcall_req' that is convenient to keep request alive automatically. + * - 'afb_req_x2_subcall' that doesn't keep request alive automatically. + * + * @param req The request + * @param api The api name of the method to call + * @param verb The verb name of the method to call + * @param args The arguments to pass to the method + * @param flags The bit field of flags for the subcall as defined by @ref afb_req_x2_subcall_flags + * @param object a pointer where the replied JSON object is stored must be freed using @ref json_object_put (can be NULL) + * @param error a pointer where a copy of the replied error is stored must be freed using @ref free (can be NULL) + * @param info a pointer where a copy of the replied info is stored must be freed using @ref free (can be NULL) + * + * @return 0 in case of success or -1 in case of error + */ +static inline +int afb_req_x2_subcall_sync( + struct afb_req_x2 *req, + const char *api, + const char *verb, + struct json_object *args, + int flags, + struct json_object **object, + char **error, + char **info) +{ + return req->itf->subcallsync(req, api, verb, args, flags, object, error, info); +} diff --git a/include/afb/afb-request-itf.h b/include/afb/afb-request-itf.h deleted file mode 100644 index 44066c66..00000000 --- a/include/afb/afb-request-itf.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2016, 2017, 2018 "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 - -/* defined here */ -struct afb_arg; -struct afb_request; -struct afb_request_itf; - -/* referenced here */ -#include <stdarg.h> -struct json_object; -struct afb_req; -struct afb_event; -struct afb_eventid; -struct afb_dynapi; -struct afb_stored_req; - -/* - * Describes an argument (or parameter) of a request - */ -struct afb_arg -{ - const char *name; /* name of the argument or NULL if invalid */ - const char *value; /* string representation of the value of the argument */ - /* original filename of the argument if path != NULL */ - const char *path; /* if not NULL, path of the received file for the argument */ - /* when the request is finalized this file is removed */ -}; - -/* - * structure for the request - */ -struct afb_request -{ - /* interface for the request */ - const struct afb_request_itf *itf; - - /* current dynapi (if any) */ - struct afb_dynapi *dynapi; - - /* closure associated with the callback processing the verb of the request - * as given at its declaration */ - void *vcbdata; - - /* the name of the called verb */ - const char *api; - - /* the name of the called verb */ - const char *verb; -}; - -/* - * Interface for handling requests. - * It records the functions to be called for the request. - * Don't use this structure directly. - * Use the helper functions - */ -struct afb_request_itf -{ - /* CAUTION: respect the order, add at the end */ - - struct json_object *(*json)( - struct afb_request *request); - - struct afb_arg (*get)( - struct afb_request *request, - const char *name); - - void (*success)( - struct afb_request *request, - struct json_object *obj, - const char *info); - - void (*fail)( - struct afb_request *request, - const char *status, - const char *info); - - void (*vsuccess)( - struct afb_request *request, - struct json_object *obj, - const char *fmt, - va_list args); - - void (*vfail)( - struct afb_request *request, - const char *status, - const char *fmt, - va_list args); - - void *(*context_get)( - struct afb_request *request); - - void (*context_set)( - struct afb_request *request, - void *value, - void (*free_value)(void*)); - - struct afb_request *(*addref)( - struct afb_request *request); - - void (*unref)( - struct afb_request *request); - - void (*session_close)( - struct afb_request *request); - - int (*session_set_LOA)( - struct afb_request *request, - unsigned level); - - int (*subscribe)( - struct afb_request *request, - struct afb_event event); - - int (*unsubscribe)( - struct afb_request *request, - struct afb_event event); - - void (*subcall)( - struct afb_request *request, - const char *api, - const char *verb, - struct json_object *args, - void (*callback)(void*, int, struct json_object*), - void *cb_closure); - - int (*subcallsync)( - struct afb_request *request, - const char *api, - const char *verb, - struct json_object *args, - struct json_object **result); - - void (*vverbose)( - struct afb_request *request, - int level, - const char *file, - int line, - const char * func, - const char *fmt, - va_list args); - - struct afb_stored_req *(*store)( - struct afb_request *request); - - void (*subcall_req)( - struct afb_request *request, - const char *api, - const char *verb, - struct json_object *args, - void (*callback)(void*, int, struct json_object*, struct afb_req), - void *cb_closure); - - int (*has_permission)( - struct afb_request *request, - const char *permission); - - char *(*get_application_id)( - struct afb_request *request); - - void *(*context_make)( - struct afb_request *request, - int replace, - void *(*create_value)(void *creation_closure), - void (*free_value)(void*), - void *creation_closure); - - int (*subscribe_eventid)( - struct afb_request *request, - struct afb_eventid *eventid); - - int (*unsubscribe_eventid)( - struct afb_request *request, - struct afb_eventid *eventid); - - void (*subcall_request)( - struct afb_request *request, - const char *api, - const char *verb, - struct json_object *args, - void (*callback)(void*, int, struct json_object*, struct afb_request *request), - void *cb_closure); - - int (*get_uid)( - struct afb_request *request); - -}; - diff --git a/include/afb/afb-request.h b/include/afb/afb-request.h deleted file mode 100644 index 8e909bba..00000000 --- a/include/afb/afb-request.h +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (C) 2016, 2017, 2018 "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 "afb-request-itf.h" - -static inline struct afb_dynapi *afb_request_get_dynapi(struct afb_request *request) -{ - return request->dynapi; -} - -static inline void *afb_request_get_vcbdata(struct afb_request *request) -{ - return request->vcbdata; -} - -static inline const char *afb_request_get_api(struct afb_request *request) -{ - return request->api; -} - -static inline const char *afb_request_get_verb(struct afb_request *request) -{ - return request->verb; -} - -/* - * Gets from the request 'request' the argument of 'name'. - * Returns a PLAIN structure of type 'struct afb_arg'. - * When the argument of 'name' is not found, all fields of result are set to NULL. - * When the argument of 'name' is found, the fields are filled, - * in particular, the field 'result.name' is set to 'name'. - * - * There is a special name value: the empty string. - * The argument of name "" is defined only if the request was made using - * an HTTP POST of Content-Type "application/json". In that case, the - * argument of name "" receives the value of the body of the HTTP request. - */ -static inline struct afb_arg afb_request_get(struct afb_request *request, const char *name) -{ - return request->itf->get(request, name); -} - -/* - * Gets from the request 'request' the string value of the argument of 'name'. - * Returns NULL if when there is no argument of 'name'. - * Returns the value of the argument of 'name' otherwise. - * - * Shortcut for: afb_request_get(request, name).value - */ -static inline const char *afb_request_value(struct afb_request *request, const char *name) -{ - return afb_request_get(request, name).value; -} - -/* - * Gets from the request 'request' the path for file attached to the argument of 'name'. - * Returns NULL if when there is no argument of 'name' or when there is no file. - * Returns the path of the argument of 'name' otherwise. - * - * Shortcut for: afb_request_get(request, name).path - */ -static inline const char *afb_request_path(struct afb_request *request, const char *name) -{ - return afb_request_get(request, name).path; -} - -/* - * Gets from the request 'request' the json object hashing the arguments. - * The returned object must not be released using 'json_object_put'. - */ -static inline struct json_object *afb_request_json(struct afb_request *request) -{ - return request->itf->json(request); -} - -/* - * Sends a reply of kind success to the request 'request'. - * The status of the reply is automatically set to "success". - * Its send the object 'obj' (can be NULL) with an - * informationnal comment 'info (can also be NULL). - * - * For convenience, the function calls 'json_object_put' for 'obj'. - * Thus, in the case where 'obj' should remain available after - * the function returns, the function 'json_object_get' shall be used. - */ -static inline void afb_request_success(struct afb_request *request, struct json_object *obj, const char *info) -{ - request->itf->success(request, obj, info); -} - -/* - * Same as 'afb_request_success' but the 'info' is a formatting - * string followed by arguments. - * - * For convenience, the function calls 'json_object_put' for 'obj'. - * Thus, in the case where 'obj' should remain available after - * the function returns, the function 'json_object_get' shall be used. - */ -static inline void afb_request_success_f(struct afb_request *request, struct json_object *obj, const char *info, ...) __attribute__((format(printf, 3, 4))); -static inline void afb_request_success_f(struct afb_request *request, struct json_object *obj, const char *info, ...) -{ - va_list args; - va_start(args, info); - request->itf->vsuccess(request, obj, info, args); - va_end(args); -} - -/* - * Same as 'afb_request_success_f' but the arguments to the format 'info' - * are given as a variable argument list instance. - * - * For convenience, the function calls 'json_object_put' for 'obj'. - * Thus, in the case where 'obj' should remain available after - * the function returns, the function 'json_object_get' shall be used. - */ -static inline void afb_request_success_v(struct afb_request *request, struct json_object *obj, const char *info, va_list args) -{ - request->itf->vsuccess(request, obj, info, args); -} - -/* - * Sends a reply of kind failure to the request 'request'. - * The status of the reply is set to 'status' and an - * informationnal comment 'info' (can also be NULL) can be added. - * - * Note that calling afb_request_fail("success", info) is equivalent - * to call afb_request_success(NULL, info). Thus even if possible it - * is strongly recommanded to NEVER use "success" for status. - */ -static inline void afb_request_fail(struct afb_request *request, const char *status, const char *info) -{ - request->itf->fail(request, status, info); -} - -/* - * Same as 'afb_request_fail' but the 'info' is a formatting - * string followed by arguments. - */ -static inline void afb_request_fail_f(struct afb_request *request, const char *status, const char *info, ...) __attribute__((format(printf, 3, 4))); -static inline void afb_request_fail_f(struct afb_request *request, const char *status, const char *info, ...) -{ - va_list args; - va_start(args, info); - request->itf->vfail(request, status, info, args); - va_end(args); -} - -/* - * Same as 'afb_request_fail_f' but the arguments to the format 'info' - * are given as a variable argument list instance. - */ -static inline void afb_request_fail_v(struct afb_request *request, const char *status, const char *info, va_list args) -{ - request->itf->vfail(request, status, info, args); -} - -/* - * Gets the pointer stored by the binding for the session of 'request'. - * When the binding has not yet recorded a pointer, NULL is returned. - */ -static inline void *afb_request_context_get(struct afb_request *request) -{ - return request->itf->context_make(request, 0, 0, 0, 0); -} - -/* - * Stores for the binding the pointer 'context' to the session of 'request'. - * The function 'free_context' will be called when the session is closed - * or if binding stores an other pointer. - */ -static inline void afb_request_context_set(struct afb_request *request, void *context, void (*free_context)(void*)) -{ - request->itf->context_make(request, 1, 0, free_context, context); -} - -/* - * Gets the pointer stored by the binding for the session of 'request'. - * If no previous pointer is stored or if 'replace' is not zero, a new value - * is generated using the function 'create_context' called with the 'closure'. - * If 'create_context' is NULL the generated value is 'closure'. - * When a value is created, the function 'free_context' is recorded and will - * be called (with the created value as argument) to free the created value when - * it is not more used. - * This function is atomic: it ensures that 2 threads will not race together. - */ -static inline void *afb_request_context(struct afb_request *request, int replace, void *(*create_context)(void *closure), void (*free_context)(void*), void *closure) -{ - return request->itf->context_make(request, replace, create_context, free_context, closure); -} - -/* - * Frees the pointer stored by the binding for the session of 'request' - * and sets it to NULL. - * - * Shortcut for: afb_request_context_set(request, NULL, NULL) - */ -static inline void afb_request_context_clear(struct afb_request *request) -{ - request->itf->context_make(request, 1, 0, 0, 0); -} - -/* - * Adds one to the count of references of 'request'. - * This function MUST be called by asynchronous implementations - * of verbs if no reply was sent before returning. - */ -static inline struct afb_request *afb_request_addref(struct afb_request *request) -{ - return request->itf->addref(request); -} - -/* - * Substracts one to the count of references of 'request'. - * This function MUST be called by asynchronous implementations - * of verbs after sending the asynchronous reply. - */ -static inline void afb_request_unref(struct afb_request *request) -{ - request->itf->unref(request); -} - -/* - * Closes the session associated with 'request' - * and delete all associated contexts. - */ -static inline void afb_request_session_close(struct afb_request *request) -{ - request->itf->session_close(request); -} - -/* - * Sets the level of assurance of the session of 'request' - * to 'level'. The effect of this function is subject of - * security policies. - * Returns 1 on success or 0 if failed. - */ -static inline int afb_request_session_set_LOA(struct afb_request *request, unsigned level) -{ - return request->itf->session_set_LOA(request, level); -} - -/* - * Establishes for the client link identified by 'request' a subscription - * to the 'event'. - * Returns 0 in case of successful subscription or -1 in case of error. - */ -static inline int afb_request_subscribe(struct afb_request *request, struct afb_eventid *eventid) -{ - return request->itf->subscribe_eventid(request, eventid); -} - -/* - * Revokes the subscription established to the 'event' for the client - * link identified by 'request'. - * Returns 0 in case of successful subscription or -1 in case of error. - */ -static inline int afb_request_unsubscribe(struct afb_request *request, struct afb_eventid *eventid) -{ - return request->itf->unsubscribe_eventid(request, eventid); -} - -/* - * Makes a call to the method of name 'api' / 'verb' with the object 'args'. - * This call is made in the context of the request 'request'. - * On completion, the function 'callback' is invoked with the - * 'closure' given at call and two other parameters: 'iserror' and 'result'. - * 'status' is 0 on success or negative when on an error reply. - * 'result' is the json object of the reply, you must not call json_object_put - * on the result. - * - * For convenience, the function calls 'json_object_put' for 'args'. - * Thus, in the case where 'args' should remain available after - * the function returns, the function 'json_object_get' shall be used. - * - * See also: - * - 'afb_request_subcall_req' that is convenient to keep request alive automatically. - * - 'afb_request_subcall_sync' the synchronous version - */ -static inline void afb_request_subcall(struct afb_request *request, const char *api, const char *verb, struct json_object *args, void (*callback)(void *closure, int iserror, struct json_object *result, struct afb_request *request), void *closure) -{ - request->itf->subcall_request(request, api, verb, args, callback, closure); -} - -/* - * Makes a call to the method of name 'api' / 'verb' with the object 'args'. - * This call is made in the context of the request 'request'. - * This call is synchronous, it waits untill completion of the request. - * It returns 0 on success or a negative value on error answer. - * The object pointed by 'result' is filled and must be released by the caller - * after its use by calling 'json_object_put'. - * - * For convenience, the function calls 'json_object_put' for 'args'. - * Thus, in the case where 'args' should remain available after - * the function returns, the function 'json_object_get' shall be used. - * - * See also: - * - 'afb_request_subcall_req' that is convenient to keep request alive automatically. - * - 'afb_request_subcall' that doesn't keep request alive automatically. - */ -static inline int afb_request_subcall_sync(struct afb_request *request, const char *api, const char *verb, struct json_object *args, struct json_object **result) -{ - return request->itf->subcallsync(request, api, verb, args, result); -} - -/* - * Send associated to 'request' a message described by 'fmt' and following parameters - * to the journal for the verbosity 'level'. - * - * 'file', 'line' and 'func' are indicators of position of the code in source files - * (see macros __FILE__, __LINE__ and __func__). - * - * 'level' is defined by syslog standard: - * EMERGENCY 0 System is unusable - * ALERT 1 Action must be taken immediately - * CRITICAL 2 Critical conditions - * ERROR 3 Error conditions - * WARNING 4 Warning conditions - * NOTICE 5 Normal but significant condition - * INFO 6 Informational - * DEBUG 7 Debug-level messages - */ -static inline void afb_request_verbose(struct afb_request *request, int level, const char *file, int line, const char * func, const char *fmt, ...) __attribute__((format(printf, 6, 7))); -static inline void afb_request_verbose(struct afb_request *request, int level, const char *file, int line, const char * func, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - request->itf->vverbose(request, level, file, line, func, fmt, args); - va_end(args); -} - -/* macro for setting file, line and function automatically */ -# if !defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DETAILS) -#define AFB_REQUEST_VERBOSE(request,level,...) afb_request_verbose(request,level,__FILE__,__LINE__,__func__,__VA_ARGS__) -#else -#define AFB_REQUEST_VERBOSE(request,level,...) afb_request_verbose(request,level,NULL,0,NULL,__VA_ARGS__) -#endif - -/* - * Check whether the 'permission' is granted or not to the client - * identified by 'request'. - * - * Returns 1 if the permission is granted or 0 otherwise. - */ -static inline int afb_request_has_permission(struct afb_request *request, const char *permission) -{ - return request->itf->has_permission(request, permission); -} - -/* - * Get the application identifier of the client application for the - * request 'request'. - * - * Returns the application identifier or NULL when the application - * can not be identified. - * - * The returned value if not NULL must be freed by the caller - */ -static inline char *afb_request_get_application_id(struct afb_request *request) -{ - return request->itf->get_application_id(request); -} - -/* - * Get the user identifier (UID) of the client for the - * request 'request'. - * - * Returns -1 when the application can not be identified. - */ -static inline int afb_request_get_uid(struct afb_request *request) -{ - return request->itf->get_uid(request); -} - diff --git a/include/afb/afb-service-itf.h b/include/afb/afb-service-itf-x1.h index dd79bdde..fcdd08e1 100644 --- a/include/afb/afb-service-itf.h +++ b/include/afb/afb-service-itf-x1.h @@ -17,32 +17,35 @@ #pragma once -/* avoid inclusion of <json-c/json.h> */ -struct json_object; +struct afb_api_x3; -/* +/** + * @deprecated use bindings version 3 + * * Interface for internal of services * It records the functions to be called for the request. * Don't use this structure directly. * Use the helper functions documented below. */ -struct afb_service_itf +struct afb_service_itf_x1 { /* CAUTION: respect the order, add at the end */ - void (*call)(void *closure, const char *api, const char *verb, struct json_object *args, + void (*call)(struct afb_api_x3 *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *callback_closure); - int (*call_sync)(void *closure, const char *api, const char *verb, struct json_object *args, + int (*call_sync)(struct afb_api_x3 *closure, const char *api, const char *verb, struct json_object *args, struct json_object **result); }; -/* +/** + * @deprecated use bindings version 3 + * * Object that encapsulate accesses to service items */ -struct afb_service +struct afb_service_x1 { - const struct afb_service_itf *itf; - void *closure; + const struct afb_service_itf_x1 *itf; + struct afb_api_x3 *closure; }; diff --git a/include/afb/afb-service-v1.h b/include/afb/afb-service-v1.h index 6a24ecb0..a3265af8 100644 --- a/include/afb/afb-service-v1.h +++ b/include/afb/afb-service-v1.h @@ -17,9 +17,11 @@ #pragma once -#include "afb-service-itf.h" +#include "afb-service-itf-x1.h" /** + * @deprecated use bindings version 3 + * * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. * The result of the call is delivered to the 'callback' function with the 'callback_closure'. * @@ -42,7 +44,7 @@ * @see also 'afb_req_subcall' */ static inline void afb_service_call_v1( - struct afb_service service, + struct afb_service_x1 service, const char *api, const char *verb, struct json_object *args, @@ -53,6 +55,8 @@ static inline void afb_service_call_v1( } /** + * @deprecated use bindings version 3 + * * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. * 'result' will receive the response. * @@ -71,7 +75,7 @@ static inline void afb_service_call_v1( * @see also 'afb_req_subcall' */ static inline int afb_service_call_sync_v1( - struct afb_service service, + struct afb_service_x1 service, const char *api, const char *verb, struct json_object *args, diff --git a/include/afb/afb-service-v2.h b/include/afb/afb-service-v2.h index df751bd5..da59786d 100644 --- a/include/afb/afb-service-v2.h +++ b/include/afb/afb-service-v2.h @@ -17,9 +17,11 @@ #pragma once -#include "afb-service-itf.h" +#include "afb-service-itf-x1.h" /** + * @deprecated use bindings version 3 + * * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. * The result of the call is delivered to the 'callback' function with the 'callback_closure'. * @@ -51,6 +53,8 @@ static inline void afb_service_call_v2( } /** + * @deprecated use bindings version 3 + * * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding. * 'result' will receive the response. * diff --git a/include/afb/afb-session-v1.h b/include/afb/afb-session-v1.h deleted file mode 100644 index a606679b..00000000 --- a/include/afb/afb-session-v1.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2016, 2017, 2018 "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 - -/* - * Enum for Session/Token/Assurance middleware. - */ -enum afb_session_flags_v1 -{ - AFB_SESSION_NONE_V1 = 0, /* nothing required */ - AFB_SESSION_CREATE_V1 = 1, /* Obsolete */ - AFB_SESSION_CLOSE_V1 = 2, /* After token authentification, closes the session at end */ - AFB_SESSION_RENEW_V1 = 4, /* After token authentification, refreshes the token at end */ - AFB_SESSION_CHECK_V1 = 8, /* Requires token authentification */ - - AFB_SESSION_LOA_GE_V1 = 16, /* check that the LOA is greater or equal to the given value */ - AFB_SESSION_LOA_LE_V1 = 32, /* check that the LOA is lesser or equal to the given value */ - AFB_SESSION_LOA_EQ_V1 = 48, /* check that the LOA is equal to the given value */ - - AFB_SESSION_LOA_SHIFT_V1 = 6, /* shift for LOA */ - AFB_SESSION_LOA_MASK_V1 = 7, /* mask for LOA */ - - AFB_SESSION_LOA_0_V1 = 0, /* value for LOA of 0 */ - AFB_SESSION_LOA_1_V1 = 64, /* value for LOA of 1 */ - AFB_SESSION_LOA_2_V1 = 128, /* value for LOA of 2 */ - AFB_SESSION_LOA_3_V1 = 192, /* value for LOA of 3 */ - AFB_SESSION_LOA_4_V1 = 256, /* value for LOA of 4 */ - - AFB_SESSION_LOA_LE_0_V1 = AFB_SESSION_LOA_LE_V1 | AFB_SESSION_LOA_0_V1, /* check LOA <= 0 */ - AFB_SESSION_LOA_LE_1_V1 = AFB_SESSION_LOA_LE_V1 | AFB_SESSION_LOA_1_V1, /* check LOA <= 1 */ - AFB_SESSION_LOA_LE_2_V1 = AFB_SESSION_LOA_LE_V1 | AFB_SESSION_LOA_2_V1, /* check LOA <= 2 */ - AFB_SESSION_LOA_LE_3_V1 = AFB_SESSION_LOA_LE_V1 | AFB_SESSION_LOA_3_V1, /* check LOA <= 3 */ - - AFB_SESSION_LOA_EQ_0_V1 = AFB_SESSION_LOA_EQ_V1 | AFB_SESSION_LOA_0_V1, /* check LOA == 0 */ - AFB_SESSION_LOA_EQ_1_V1 = AFB_SESSION_LOA_EQ_V1 | AFB_SESSION_LOA_1_V1, /* check LOA == 1 */ - AFB_SESSION_LOA_EQ_2_V1 = AFB_SESSION_LOA_EQ_V1 | AFB_SESSION_LOA_2_V1, /* check LOA == 2 */ - AFB_SESSION_LOA_EQ_3_V1 = AFB_SESSION_LOA_EQ_V1 | AFB_SESSION_LOA_3_V1, /* check LOA == 3 */ - - AFB_SESSION_LOA_GE_0_V1 = AFB_SESSION_LOA_GE_V1 | AFB_SESSION_LOA_0_V1, /* check LOA >= 0 */ - AFB_SESSION_LOA_GE_1_V1 = AFB_SESSION_LOA_GE_V1 | AFB_SESSION_LOA_1_V1, /* check LOA >= 1 */ - AFB_SESSION_LOA_GE_2_V1 = AFB_SESSION_LOA_GE_V1 | AFB_SESSION_LOA_2_V1, /* check LOA >= 2 */ - AFB_SESSION_LOA_GE_3_V1 = AFB_SESSION_LOA_GE_V1 | AFB_SESSION_LOA_3_V1 /* check LOA >= 3 */ -}; - diff --git a/include/afb/afb-session-v2.h b/include/afb/afb-session-v2.h deleted file mode 100644 index 3f940ed6..00000000 --- a/include/afb/afb-session-v2.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2016, 2017, 2018 "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 - -/* - * Enum for Session/Token/Assurance middleware. - */ -enum afb_session_flags_v2 -{ - AFB_SESSION_LOA_MASK_V2 = 3, /* mask for LOA */ - - AFB_SESSION_LOA_0_V2 = 0, /* value for LOA of 0 */ - AFB_SESSION_LOA_1_V2 = 1, /* value for LOA of 1 */ - AFB_SESSION_LOA_2_V2 = 2, /* value for LOA of 2 */ - AFB_SESSION_LOA_3_V2 = 3, /* value for LOA of 3 */ - - AFB_SESSION_CHECK_V2 = 4, /* Requires token authentification */ - AFB_SESSION_REFRESH_V2 = 8, /* After token authentification, refreshes the token at end */ - AFB_SESSION_CLOSE_V2 = 16, /* After token authentification, closes the session at end */ - - AFB_SESSION_NONE_V2 = 0 /* nothing required */ -}; - diff --git a/include/afb/afb-session-x1.h b/include/afb/afb-session-x1.h new file mode 100644 index 00000000..776cb8f5 --- /dev/null +++ b/include/afb/afb-session-x1.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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 + +/** + * @deprecated use bindings version 3 + * + * Enum for Session/Token/Assurance of bindings version 1. + */ +enum afb_session_flags_x1 +{ + AFB_SESSION_NONE_X1 = 0, /**< nothing required */ + AFB_SESSION_CREATE_X1 = 1, /**< Obsolete */ + AFB_SESSION_CLOSE_X1 = 2, /**< After token authentification, closes the session at end */ + AFB_SESSION_RENEW_X1 = 4, /**< After token authentification, refreshes the token at end */ + AFB_SESSION_CHECK_X1 = 8, /**< Requires token authentification */ + + AFB_SESSION_LOA_GE_X1 = 16, /**< check that the LOA is greater or equal to the given value */ + AFB_SESSION_LOA_LE_X1 = 32, /**< check that the LOA is lesser or equal to the given value */ + AFB_SESSION_LOA_EQ_X1 = 48, /**< check that the LOA is equal to the given value */ + + AFB_SESSION_LOA_SHIFT_X1 = 6, /**< shift for LOA */ + AFB_SESSION_LOA_MASK_X1 = 7, /**< mask for LOA */ + + AFB_SESSION_LOA_0_X1 = 0, /**< value for LOA of 0 */ + AFB_SESSION_LOA_1_X1 = 64, /**< value for LOA of 1 */ + AFB_SESSION_LOA_2_X1 = 128, /**< value for LOA of 2 */ + AFB_SESSION_LOA_3_X1 = 192, /**< value for LOA of 3 */ + AFB_SESSION_LOA_4_X1 = 256, /**< value for LOA of 4 */ + + AFB_SESSION_LOA_LE_0_X1 = AFB_SESSION_LOA_LE_X1 | AFB_SESSION_LOA_0_X1, /**< check LOA <= 0 */ + AFB_SESSION_LOA_LE_1_X1 = AFB_SESSION_LOA_LE_X1 | AFB_SESSION_LOA_1_X1, /**< check LOA <= 1 */ + AFB_SESSION_LOA_LE_2_X1 = AFB_SESSION_LOA_LE_X1 | AFB_SESSION_LOA_2_X1, /**< check LOA <= 2 */ + AFB_SESSION_LOA_LE_3_X1 = AFB_SESSION_LOA_LE_X1 | AFB_SESSION_LOA_3_X1, /**< check LOA <= 3 */ + + AFB_SESSION_LOA_EQ_0_X1 = AFB_SESSION_LOA_EQ_X1 | AFB_SESSION_LOA_0_X1, /**< check LOA == 0 */ + AFB_SESSION_LOA_EQ_1_X1 = AFB_SESSION_LOA_EQ_X1 | AFB_SESSION_LOA_1_X1, /**< check LOA == 1 */ + AFB_SESSION_LOA_EQ_2_X1 = AFB_SESSION_LOA_EQ_X1 | AFB_SESSION_LOA_2_X1, /**< check LOA == 2 */ + AFB_SESSION_LOA_EQ_3_X1 = AFB_SESSION_LOA_EQ_X1 | AFB_SESSION_LOA_3_X1, /**< check LOA == 3 */ + + AFB_SESSION_LOA_GE_0_X1 = AFB_SESSION_LOA_GE_X1 | AFB_SESSION_LOA_0_X1, /**< check LOA >= 0 */ + AFB_SESSION_LOA_GE_1_X1 = AFB_SESSION_LOA_GE_X1 | AFB_SESSION_LOA_1_X1, /**< check LOA >= 1 */ + AFB_SESSION_LOA_GE_2_X1 = AFB_SESSION_LOA_GE_X1 | AFB_SESSION_LOA_2_X1, /**< check LOA >= 2 */ + AFB_SESSION_LOA_GE_3_X1 = AFB_SESSION_LOA_GE_X1 | AFB_SESSION_LOA_3_X1 /**< check LOA >= 3 */ +}; + diff --git a/include/afb/afb-session-x2.h b/include/afb/afb-session-x2.h new file mode 100644 index 00000000..b4a24c77 --- /dev/null +++ b/include/afb/afb-session-x2.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2016, 2017, 2018 "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 + +/** + * Enum for Session/Token/Assurance middleware of bindings version 2 and 3. + */ +enum afb_session_flags_x2 +{ + AFB_SESSION_LOA_MASK_X2 = 3, /**< mask for LOA */ + + AFB_SESSION_LOA_0_X2 = 0, /**< value for LOA of 0 */ + AFB_SESSION_LOA_1_X2 = 1, /**< value for LOA of 1 */ + AFB_SESSION_LOA_2_X2 = 2, /**< value for LOA of 2 */ + AFB_SESSION_LOA_3_X2 = 3, /**< value for LOA of 3 */ + + AFB_SESSION_CHECK_X2 = 4, /**< Requires token authentification */ + AFB_SESSION_REFRESH_X2 = 8, /**< After token authentification, refreshes the token at end */ + AFB_SESSION_CLOSE_X2 = 16, /**< After token authentification, closes the session at end */ + + AFB_SESSION_NONE_X2 = 0 /**< nothing required */ +}; + diff --git a/include/afb/afb-verbosity.h b/include/afb/afb-verbosity.h index 9f122056..dd34f841 100644 --- a/include/afb/afb-verbosity.h +++ b/include/afb/afb-verbosity.h @@ -23,9 +23,42 @@ #define AFB_VERBOSITY_LEVEL_INFO 3 #define AFB_VERBOSITY_LEVEL_DEBUG 4 -#define _AFB_SYSLOG_LEVEL_ERROR_ 3 -#define _AFB_SYSLOG_LEVEL_WARNING_ 4 -#define _AFB_SYSLOG_LEVEL_NOTICE_ 5 -#define _AFB_SYSLOG_LEVEL_INFO_ 6 -#define _AFB_SYSLOG_LEVEL_DEBUG_ 7 +#define AFB_SYSLOG_LEVEL_EMERGENCY 0 +#define AFB_SYSLOG_LEVEL_ALERT 1 +#define AFB_SYSLOG_LEVEL_CRITICAL 2 +#define AFB_SYSLOG_LEVEL_ERROR 3 +#define AFB_SYSLOG_LEVEL_WARNING 4 +#define AFB_SYSLOG_LEVEL_NOTICE 5 +#define AFB_SYSLOG_LEVEL_INFO 6 +#define AFB_SYSLOG_LEVEL_DEBUG 7 + +#define AFB_VERBOSITY_LEVEL_WANT(verbosity,level) ((verbosity) >= (level)) + +#define AFB_VERBOSITY_LEVEL_WANT_ERROR(x) AFB_VERBOSITY_LEVEL_WANT(x,AFB_VERBOSITY_LEVEL_ERROR) +#define AFB_VERBOSITY_LEVEL_WANT_WARNING(x) AFB_VERBOSITY_LEVEL_WANT(x,AFB_VERBOSITY_LEVEL_WARNING) +#define AFB_VERBOSITY_LEVEL_WANT_NOTICE(x) AFB_VERBOSITY_LEVEL_WANT(x,AFB_VERBOSITY_LEVEL_NOTICE) +#define AFB_VERBOSITY_LEVEL_WANT_INFO(x) AFB_VERBOSITY_LEVEL_WANT(x,AFB_VERBOSITY_LEVEL_INFO) +#define AFB_VERBOSITY_LEVEL_WANT_DEBUG(x) AFB_VERBOSITY_LEVEL_WANT(x,AFB_VERBOSITY_LEVEL_DEBUG) + +#define AFB_SYSLOG_MASK_WANT(verbomask,level) ((verbomask) & (1 << (level))) + +#define AFB_SYSLOG_MASK_WANT_EMERGENCY(x) AFB_SYSLOG_MASK_WANT(x,AFB_SYSLOG_LEVEL_EMERGENCY) +#define AFB_SYSLOG_MASK_WANT_ALERT(x) AFB_SYSLOG_MASK_WANT(x,AFB_SYSLOG_LEVEL_ALERT) +#define AFB_SYSLOG_MASK_WANT_CRITICAL(x) AFB_SYSLOG_MASK_WANT(x,AFB_SYSLOG_LEVEL_CRITICAL) +#define AFB_SYSLOG_MASK_WANT_ERROR(x) AFB_SYSLOG_MASK_WANT(x,AFB_SYSLOG_LEVEL_ERROR) +#define AFB_SYSLOG_MASK_WANT_WARNING(x) AFB_SYSLOG_MASK_WANT(x,AFB_SYSLOG_LEVEL_WARNING) +#define AFB_SYSLOG_MASK_WANT_NOTICE(x) AFB_SYSLOG_MASK_WANT(x,AFB_SYSLOG_LEVEL_NOTICE) +#define AFB_SYSLOG_MASK_WANT_INFO(x) AFB_SYSLOG_MASK_WANT(x,AFB_SYSLOG_LEVEL_INFO) +#define AFB_SYSLOG_MASK_WANT_DEBUG(x) AFB_SYSLOG_MASK_WANT(x,AFB_SYSLOG_LEVEL_DEBUG) + +#define AFB_SYSLOG_LEVEL_FROM_VERBOSITY(x) ((x) + (AFB_SYSLOG_LEVEL_ERROR - AFB_VERBOSITY_LEVEL_ERROR)) +#define AFB_SYSLOG_LEVEL_TO_VERBOSITY(x) ((x) + (AFB_VERBOSITY_LEVEL_ERROR - AFB_SYSLOG_LEVEL_ERROR)) + +static inline int _afb_verbomask_to_upper_level_(int verbomask) +{ + int result = 0; + while ((verbomask >>= 1) && result < AFB_SYSLOG_LEVEL_DEBUG) + result++; + return result; +} |