/* * Copyright (C) 2015-2020 "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 !defined(AFB_BINDING_NO_ROOT) /* use with caution, see @ref validity-v3 */ #if AFB_BINDING_VERSION != 3 extern #endif struct afb_api_x3 *afbBindingV3root __attribute__((weak)); #endif /** * 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_x3_verbose(api,level,__FILE__,__LINE__,NULL,__VA_ARGS__); \ else afb_api_x3_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_x3_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_api_wants_log_level((api),(llevel))) AFB_API_VERBOSE_V3((api),(llevel),__VA_ARGS__); }while(0) #define _AFB_REQ_LOGGING_V3_(req,llevel,...) \ do{ if(afb_req_wants_log_level((req),(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) #define afb_daemon_get_user_bus_v3() afb_api_get_user_bus(afbBindingV3root) #define afb_daemon_get_system_bus_v3() afb_api_get_system_bus(afbBindingV3root) #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(afbBindingV3root,__VA_ARGS__) #define afb_service_call_sync_v3(...) afb_api_call_sync(afbBindingV3root,__VA_ARGS__) #define afb_service_call_legacy_v3(...) afb_api_call_legacy(afbBindingV3root,__VA_ARGS__) #define afb_service_call_sync_legacy_v3(...) afb_api_call_sync_legacy(afbBindingV3root,__VA_ARGS__)