From 95c29ef579d6320a721f96d7146efd10f74a201b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Mon, 22 May 2017 16:37:28 +0200 Subject: [PATCH] Bindings V2: Remove explicit references to daemon/service MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Usage shown that managing daemon interface and service interface wasn't obvious. This evolution hides the complexity by setting up an internal hidden variable. Change-Id: I667b1ee4e3a7b5ad29d712ee20ad5dd1878b97f3 Signed-off-by: José Bollo --- include/afb/afb-binding-v1.h | 25 +++- include/afb/afb-binding-v2.h | 102 +++++++++++---- include/afb/afb-binding.h | 11 +- include/afb/afb-daemon-common.h | 48 +++++++ include/afb/{afb-daemon-itf.h => afb-daemon-v1.h} | 50 ++----- include/afb/afb-daemon-v2.h | 118 +++++++++++++++++ include/afb/afb-service-common.h | 45 +++++++ .../afb/{afb-service-itf.h => afb-service-v1.h} | 28 +--- include/afb/afb-service-v2.h | 48 +++++++ src/CMakeLists.txt | 1 - src/afb-api-so-v1.c | 33 ++--- src/afb-api-so-v2.c | 143 +++++++++++++++++---- src/afb-api-so-v2.h | 3 +- src/afb-api-so.c | 23 ++-- src/afb-ditf.c | 28 ++-- src/afb-ditf.h | 27 +--- src/afb-monitor.c | 11 +- src/afb-svc.c | 67 ++++------ src/afb-svc.h | 8 +- src/genskel/genskel.c | 8 +- src/verbose.c | 2 +- 21 files changed, 588 insertions(+), 241 deletions(-) create mode 100644 include/afb/afb-daemon-common.h rename include/afb/{afb-daemon-itf.h => afb-daemon-v1.h} (58%) create mode 100644 include/afb/afb-daemon-v2.h create mode 100644 include/afb/afb-service-common.h rename include/afb/{afb-service-itf.h => afb-service-v1.h} (72%) create mode 100644 include/afb/afb-service-v2.h diff --git a/include/afb/afb-binding-v1.h b/include/afb/afb-binding-v1.h index d9b33f1c..e6f322fb 100644 --- a/include/afb/afb-binding-v1.h +++ b/include/afb/afb-binding-v1.h @@ -17,10 +17,17 @@ #pragma once +struct json_object; + +#include "afb-req-itf.h" +#include "afb-event-itf.h" +#include "afb-service-common.h" +#include "afb-daemon-common.h" + #include "afb-session-v1.h" +#include "afb-daemon-v1.h" +#include "afb-daemon-v1.h" -struct json_object; -struct afb_service; struct afb_binding_v1; struct afb_binding_interface_v1; @@ -43,7 +50,7 @@ struct afb_binding_interface_v1; * Be aware that the given 'interface' is not fully functionnal * because no provision is given to the name and description * of the binding. Check the function 'afbBindingV1ServiceInit' - * defined in the file because when + * defined in the file because when * the function 'afbBindingV1ServiceInit' is called, the 'interface' * is fully functionnal. */ @@ -206,6 +213,18 @@ struct afb_binding_interface_v1 # endif +#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_service_call afb_service_call_v1 + #endif diff --git a/include/afb/afb-binding-v2.h b/include/afb/afb-binding-v2.h index 91d64693..6f8eb953 100644 --- a/include/afb/afb-binding-v2.h +++ b/include/afb/afb-binding-v2.h @@ -19,24 +19,16 @@ #include -#include "afb-session-v2.h" +#include "afb-auth.h" +#include "afb-req-itf.h" +#include "afb-event-itf.h" +#include "afb-service-common.h" +#include "afb-daemon-common.h" -struct afb_service; -struct afb_daemon; -struct afb_binding_v2; +#include "afb-session-v2.h" struct json_object; -/* - * A binding V2 MUST have two exported symbols of name: - * - * - afbBindingV2 - * - afbBindingV2verbosity - * - */ -extern const struct afb_binding_v2 afbBindingV2; -extern int afbBindingV2verbosity; - /* * Description of one verb of the API provided by the binding * This enumeration is valid for bindings of type version 2 @@ -57,31 +49,73 @@ struct afb_binding_v2 const char *api; /* api name for the binding */ const char *specification; /* textual specification of the binding */ const struct afb_verb_v2 *verbs; /* array of descriptions of verbs terminated by a NULL name */ - int (*preinit)(struct afb_daemon daemon); - int (*init)(struct afb_service service); - void (*onevent)(struct afb_service service, const char *event, struct json_object *object); - unsigned concurrent: 1; /* allows concurrent requests to verbs */ + int (*preinit)(); + int (*init)(); + void (*onevent)(const char *event, struct json_object *object); + unsigned noconcurrency: 1; /* avoids concurrent requests to verbs */ +}; + +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 */ }; +/* + * A binding V2 MUST have two exported symbols of name: + * + * - afbBindingV2 + * - afbBindingV2data + * + */ +#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 + +#if AFB_BINDING_VERSION == 2 +struct afb_binding_data_v2 AFB_BINDING_DATA_NAME_V2 __attribute__ ((weak)); +#else +extern struct afb_binding_data_v2 AFB_BINDING_DATA_NAME_V2; +#endif + +#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) + /* * Macros for logging messages */ #if !defined(AFB_BINDING_PRAGMA_NO_VERBOSE_MACRO) # if !defined(AFB_BINDING_PRAGMA_NO_VERBOSE_DETAILS) -# define AFB_ERROR_V2(daemon,...) do{if(afbBindingV2verbosity>=0)afb_daemon_verbose(daemon,3,__FILE__,__LINE__,__VA_ARGS__);}while(0) -# define AFB_WARNING_V2(daemon,...) do{if(afbBindingV2verbosity>=1)afb_daemon_verbose(daemon,4,__FILE__,__LINE__,__VA_ARGS__);}while(0) -# define AFB_NOTICE_V2(daemon,...) do{if(afbBindingV2verbosity>=1)afb_daemon_verbose(daemon,5,__FILE__,__LINE__,__VA_ARGS__);}while(0) -# define AFB_INFO_V2(daemon,...) do{if(afbBindingV2verbosity>=2)afb_daemon_verbose(daemon,6,__FILE__,__LINE__,__VA_ARGS__);}while(0) -# define AFB_DEBUG_V2(daemon,...) do{if(afbBindingV2verbosity>=3)afb_daemon_verbose(daemon,7,__FILE__,__LINE__,__VA_ARGS__);}while(0) +# 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) # else -# define AFB_ERROR_V2(daemon,...) do{if(afbBindingV2verbosity>=0)afb_daemon_verbose(daemon,3,NULL,0,__VA_ARGS__);}while(0) -# define AFB_WARNING_V2(daemon,...) do{if(afbBindingV2verbosity>=1)afb_daemon_verbose(daemon,4,NULL,0,__VA_ARGS__);}while(0) -# define AFB_NOTICE_V2(daemon,...) do{if(afbBindingV2verbosity>=1)afb_daemon_verbose(daemon,5,NULL,0,__VA_ARGS__);}while(0) -# define AFB_INFO_V2(daemon,...) do{if(afbBindingV2verbosity>=2)afb_daemon_verbose(daemon,6,NULL,0,__VA_ARGS__);}while(0) -# define AFB_DEBUG_V2(daemon,...) do{if(afbBindingV2verbosity>=3)afb_daemon_verbose(daemon,7,NULL,0,__VA_ARGS__);}while(0) +# define _AFB_LOGGING_V2_(vlevel,llevel,...) \ + do{ \ + if(afbBindingV2data.verbosity>=vlevel) \ + afb_daemon_verbose_v2(llevel,NULL,0,NULL,__VA_ARGS__); \ + }while(0) # endif +# define AFB_ERROR_V2(...) _AFB_LOGGING_V2_(0,3,__VA_ARGS__) +# define AFB_WARNING_V2(...) _AFB_LOGGING_V2_(1,4,__VA_ARGS__) +# define AFB_NOTICE_V2(...) _AFB_LOGGING_V2_(1,5,__VA_ARGS__) +# define AFB_INFO_V2(...) _AFB_LOGGING_V2_(2,6,__VA_ARGS__) +# define AFB_DEBUG_V2(...) _AFB_LOGGING_V2_(3,7,__VA_ARGS__) #endif +#include "afb-daemon-v2.h" +#include "afb-service-v2.h" + +/***************************************************************************************************/ + #if AFB_BINDING_VERSION == 2 # define afb_binding afb_binding_v2 @@ -110,4 +144,16 @@ struct afb_binding_v2 # endif +#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_service_call afb_service_call_v2 + #endif diff --git a/include/afb/afb-binding.h b/include/afb/afb-binding.h index 5a6f9bc4..ac750c7a 100644 --- a/include/afb/afb-binding.h +++ b/include/afb/afb-binding.h @@ -40,15 +40,16 @@ #define AFB_BINDING_VERSION AFB_BINDING_DEFAULT_VERSION #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 +# endif +#endif + /* * Some function of the library are exported to afb-daemon. */ -#include "afb-auth.h" -#include "afb-req-itf.h" -#include "afb-event-itf.h" -#include "afb-service-itf.h" -#include "afb-daemon-itf.h" #include "afb-binding-v1.h" #include "afb-binding-v2.h" diff --git a/include/afb/afb-daemon-common.h b/include/afb/afb-daemon-common.h new file mode 100644 index 00000000..7b241492 --- /dev/null +++ b/include/afb/afb-daemon-common.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2016, 2017 "IoT.bzh" + * Author: José Bollo + * + * 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 + +/* declaration of features of libsystemd */ +struct sd_event; +struct sd_bus; + +/* + * 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); +}; + +/* + * 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-itf.h b/include/afb/afb-daemon-v1.h similarity index 58% rename from include/afb/afb-daemon-itf.h rename to include/afb/afb-daemon-v1.h index 88ce27c9..84095e04 100644 --- a/include/afb/afb-daemon-itf.h +++ b/include/afb/afb-daemon-v1.h @@ -19,39 +19,11 @@ #include -/* declaration of features of libsystemd */ -struct sd_event; -struct sd_bus; - -/* - * 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)(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); -}; - -/* - * 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 */ -}; - /* * 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(struct afb_daemon daemon) +static inline struct sd_event *afb_daemon_get_event_loop_v1(struct afb_daemon daemon) { return daemon.itf->get_event_loop(daemon.closure); } @@ -60,7 +32,7 @@ static inline struct sd_event *afb_daemon_get_event_loop(struct afb_daemon daemo * 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(struct afb_daemon daemon) +static inline struct sd_bus *afb_daemon_get_user_bus_v1(struct afb_daemon daemon) { return daemon.itf->get_user_bus(daemon.closure); } @@ -69,7 +41,7 @@ static inline struct sd_bus *afb_daemon_get_user_bus(struct afb_daemon daemon) * 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(struct afb_daemon daemon) +static inline struct sd_bus *afb_daemon_get_system_bus_v1(struct afb_daemon daemon) { return daemon.itf->get_system_bus(daemon.closure); } @@ -85,7 +57,7 @@ static inline struct sd_bus *afb_daemon_get_system_bus(struct afb_daemon daemon) * * Returns the count of clients that received the event. */ -static inline int afb_daemon_broadcast_event(struct afb_daemon daemon, const char *name, struct json_object *object) +static inline int afb_daemon_broadcast_event_v1(struct afb_daemon daemon, const char *name, struct json_object *object) { return daemon.itf->event_broadcast(daemon.closure, name, object); } @@ -94,7 +66,7 @@ static inline int afb_daemon_broadcast_event(struct afb_daemon daemon, const cha * Creates an event of 'name' and returns it. * 'daemon' MUST be the daemon given in interface when activating the binding. */ -static inline struct afb_event afb_daemon_make_event(struct afb_daemon daemon, const char *name) +static inline struct afb_event afb_daemon_make_event_v1(struct afb_daemon daemon, const char *name) { return daemon.itf->event_make(daemon.closure, name); } @@ -105,12 +77,12 @@ static inline struct afb_event afb_daemon_make_event(struct afb_daemon daemon, c * 'file' and 'line' are indicators of position of the code in source files. * 'daemon' MUST be the daemon given in interface when activating the binding. */ -static inline void afb_daemon_verbose(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(struct afb_daemon daemon, int level, const char *file, int line, const char *fmt, ...) +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, ...) { va_list args; va_start(args, fmt); - daemon.itf->vverbose(daemon.closure, level, file, line, fmt, args); + daemon.itf->vverbose_v1(daemon.closure, level, file, line, fmt, args); va_end(args); } @@ -118,7 +90,7 @@ static inline void afb_daemon_verbose(struct afb_daemon daemon, int level, const * Get the root directory file descriptor. This file descriptor can * be used with functions 'openat', 'fstatat', ... */ -static inline int afb_daemon_rootdir_get_fd(struct afb_daemon daemon) +static inline int afb_daemon_rootdir_get_fd_v1(struct afb_daemon daemon) { return daemon.itf->rootdir_get_fd(daemon.closure); } @@ -128,7 +100,7 @@ static inline int afb_daemon_rootdir_get_fd(struct afb_daemon daemon) * 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(struct afb_daemon daemon, const char *filename, int flags, const char *locale) +static inline int afb_daemon_rootdir_open_locale_v1(struct afb_daemon daemon, const char *filename, int flags, const char *locale) { return daemon.itf->rootdir_open_locale(daemon.closure, filename, flags, locale); } @@ -146,7 +118,7 @@ static inline int afb_daemon_rootdir_open_locale(struct afb_daemon daemon, const * * Returns 0 in case of success or -1 in case of error. */ -static inline int afb_daemon_queue_job(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 daemon, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout) { return daemon.itf->queue_job(daemon.closure, callback, argument, group, timeout); } diff --git a/include/afb/afb-daemon-v2.h b/include/afb/afb-daemon-v2.h new file mode 100644 index 00000000..3ecd763b --- /dev/null +++ b/include/afb/afb-daemon-v2.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2016, 2017 "IoT.bzh" + * Author: José Bollo + * + * 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 + +/* + * Retrieves the common systemd's event loop of AFB + */ +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); +} + +/* + * Retrieves the common systemd's user/session d-bus of AFB + */ +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); +} + +/* + * Retrieves the common systemd's system d-bus of AFB + */ +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); +} + +/* + * 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. + * + * Returns the count of clients that received the event. + */ +static inline int afb_daemon_broadcast_event_v2(const char *name, struct json_object *object) +{ + return afb_get_daemon_v2().itf->event_broadcast(afb_get_daemon_v2().closure, name, object); +} + +/* + * Creates an event of 'name' and returns it. + */ +static inline struct afb_event afb_daemon_make_event_v2(const char *name) +{ + return afb_get_daemon_v2().itf->event_make(afb_get_daemon_v2().closure, name); +} + +/* + * Send a message described by 'fmt' and following parameters + * to the journal for the verbosity 'level'. + * 'file' and 'line' are indicators of position of the code in source files. + */ +static inline void afb_daemon_verbose_v2(int level, const char *file, int line, const char * func, const char *fmt, ...) __attribute__((format(printf, 5, 6))); +static inline void afb_daemon_verbose_v2(int level, const char *file, int line, const char * func, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + afb_get_daemon_v2().itf->vverbose_v2(afb_get_daemon_v2().closure, level, file, line, func, fmt, args); + va_end(args); +} + +/* + * Get the root directory file descriptor. This file descriptor can + * be used with functions 'openat', 'fstatat', ... + */ +static inline int afb_daemon_rootdir_get_fd_v2() +{ + return afb_get_daemon_v2().itf->rootdir_get_fd(afb_get_daemon_v2().closure); +} + +/* + * 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) +{ + return afb_get_daemon_v2().itf->rootdir_open_locale(afb_get_daemon_v2().closure, 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_daemon_queue_job_v2(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout) +{ + return afb_get_daemon_v2().itf->queue_job(afb_get_daemon_v2().closure, callback, argument, group, timeout); +} diff --git a/include/afb/afb-service-common.h b/include/afb/afb-service-common.h new file mode 100644 index 00000000..76f8e4e4 --- /dev/null +++ b/include/afb/afb-service-common.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2016, 2017 "IoT.bzh" + * Author: José Bollo + * + * 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 + +/* avoid inclusion of */ +struct json_object; + +/* + * 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 +{ + /* CAUTION: respect the order, add at the end */ + + void (*call)(void *closure, const char *api, const char *verb, struct json_object *args, + void (*callback)(void*, int, struct json_object*), void *callback_closure); +}; + +/* + * Object that encapsulate accesses to service items + */ +struct afb_service +{ + const struct afb_service_itf *itf; + void *closure; +}; + diff --git a/include/afb/afb-service-itf.h b/include/afb/afb-service-v1.h similarity index 72% rename from include/afb/afb-service-itf.h rename to include/afb/afb-service-v1.h index e2e61dc8..6e85a293 100644 --- a/include/afb/afb-service-itf.h +++ b/include/afb/afb-service-v1.h @@ -17,32 +17,6 @@ #pragma once -/* avoid inclusion of */ -struct json_object; - -/* - * 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 -{ - /* CAUTION: respect the order, add at the end */ - - void (*call)(void *closure, const char *api, const char *verb, struct json_object *args, - void (*callback)(void*, int, struct json_object*), void *callback_closure); -}; - -/* - * Object that encapsulate accesses to service items - */ -struct afb_service -{ - const struct afb_service_itf *itf; - void *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'. @@ -63,7 +37,7 @@ struct afb_service * * @see also 'afb_req_subcall' */ -static inline void afb_service_call( +static inline void afb_service_call_v1( struct afb_service service, const char *api, const char *verb, diff --git a/include/afb/afb-service-v2.h b/include/afb/afb-service-v2.h new file mode 100644 index 00000000..84da1209 --- /dev/null +++ b/include/afb/afb-service-v2.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2016, 2017 "IoT.bzh" + * Author: José Bollo + * + * 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 + +/** + * 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'. + * + * The 'callback' receives 3 arguments: + * 1. 'closure' the user defined closure pointer 'callback_closure', + * 2. 'iserror' a boolean status being true (not null) when an error occured, + * 2. 'result' the resulting data as a JSON object. + * + * @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 + * + * @returns 0 in case of success or -1 in case of error. + * + * @see also 'afb_req_subcall' + */ +static inline void afb_service_call_v2( + const char *api, + const char *verb, + struct json_object *args, + void (*callback)(void*closure, int iserror, struct json_object *result), + void *callback_closure) +{ + afb_get_service_v2().itf->call(afb_get_service_v2().closure, api, verb, args, callback, callback_closure); +} + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0e39dc94..d253d388 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -118,7 +118,6 @@ TARGET_LINK_LIBRARIES(afb-daemon -ldl -lrt ) -link_directories( /opt/libmicrohttpd-0.9.54/lib/ ) INSTALL(TARGETS afb-daemon RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/afb-api-so-v1.c b/src/afb-api-so-v1.c index c5f20b7f..c1f27093 100644 --- a/src/afb-api-so-v1.c +++ b/src/afb-api-so-v1.c @@ -24,7 +24,7 @@ #include -#include +#include #include "afb-api.h" #include "afb-api-so-v1.h" @@ -49,9 +49,10 @@ static const char afb_api_so_v1_service_event[] = "afbBindingV1ServiceEvent"; * Description of a binding */ struct api_so_v1 { - struct afb_binding *binding; /* descriptor */ + struct afb_binding_v1 *binding; /* descriptor */ void *handle; /* context of dlopen */ struct afb_svc *service; /* handler for service started */ + struct afb_binding_interface_v1 interface; struct afb_ditf ditf; /* daemon interface */ }; @@ -125,13 +126,13 @@ static void update_hooks_cb(void *closure) static int get_verbosity_cb(void *closure) { struct api_so_v1 *desc = closure; - return desc->ditf.interface.verbosity; + return desc->interface.verbosity; } static void set_verbosity_cb(void *closure, int level) { struct api_so_v1 *desc = closure; - desc->ditf.interface.verbosity = level; + desc->interface.verbosity = level; } struct json_object *describe_cb(void *closure) @@ -151,21 +152,21 @@ struct json_object *describe_cb(void *closure) a = json_object_new_array(); json_object_object_add(f, "name", json_object_new_string(verb->name)); json_object_object_add(f, "info", json_object_new_string(verb->info)); - if (verb->session & AFB_SESSION_CLOSE) + if (verb->session & AFB_SESSION_CLOSE_V1) json_object_array_add(a, json_object_new_string("session-close")); - if (verb->session & AFB_SESSION_RENEW) + if (verb->session & AFB_SESSION_RENEW_V1) json_object_array_add(a, json_object_new_string("session-renew")); - if (verb->session & AFB_SESSION_CHECK) + if (verb->session & AFB_SESSION_CHECK_V1) json_object_array_add(a, json_object_new_string("session-check")); - if (verb->session & AFB_SESSION_LOA_EQ) { + if (verb->session & AFB_SESSION_LOA_EQ_V1) { const char *rel = "?"; char buffer[80]; - switch (verb->session & AFB_SESSION_LOA_EQ) { - case AFB_SESSION_LOA_GE: rel = ">="; break; - case AFB_SESSION_LOA_LE: rel = "<="; break; - case AFB_SESSION_LOA_EQ: rel = "=="; break; + switch (verb->session & AFB_SESSION_LOA_EQ_V1) { + case AFB_SESSION_LOA_GE_V1: rel = ">="; break; + case AFB_SESSION_LOA_LE_V1: rel = "<="; break; + case AFB_SESSION_LOA_EQ_V1: rel = "=="; break; } - snprintf(buffer, sizeof buffer, "LOA%s%d", rel, (int)((verb->session >> AFB_SESSION_LOA_SHIFT) & AFB_SESSION_LOA_MASK)); + snprintf(buffer, sizeof buffer, "LOA%s%d", rel, (int)((verb->session >> AFB_SESSION_LOA_SHIFT_V1) & AFB_SESSION_LOA_MASK_V1)); json_object_array_add(a, json_object_new_string(buffer)); } json_object_object_add(f, "flags", a); @@ -187,7 +188,7 @@ static struct afb_api_itf so_v1_api_itf = { int afb_api_so_v1_add(const char *path, void *handle, struct afb_apiset *apiset) { struct api_so_v1 *desc; - struct afb_binding *(*register_function) (const struct afb_binding_interface *interface); + struct afb_binding_v1 *(*register_function) (const struct afb_binding_interface_v1 *interface); struct afb_api afb_api; /* retrieves the register function */ @@ -205,11 +206,11 @@ int afb_api_so_v1_add(const char *path, void *handle, struct afb_apiset *apiset) desc->handle = handle; /* init the interface */ - afb_ditf_init_v1(&desc->ditf, path); + afb_ditf_init_v1(&desc->ditf, path, &desc->interface); /* init the binding */ INFO("binding [%s] calling registering function %s", path, afb_api_so_v1_register); - desc->binding = register_function(&desc->ditf.interface); + desc->binding = register_function(&desc->interface); if (desc->binding == NULL) { ERROR("binding [%s] register function failed. continuing...", path); goto error2; diff --git a/src/afb-api-so-v2.c b/src/afb-api-so-v2.c index 6aa10cf5..8dadada5 100644 --- a/src/afb-api-so-v2.c +++ b/src/afb-api-so-v2.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include "afb-api.h" @@ -42,14 +42,14 @@ * names of symbols */ static const char afb_api_so_v2_descriptor[] = "afbBindingV2"; -static const char afb_api_so_v2_verbosity[] = "afbBindingV2verbosity"; +static const char afb_api_so_v2_data[] = "afbBindingV2data"; /* * Description of a binding */ struct api_so_v2 { const struct afb_binding_v2 *binding; /* descriptor */ - int *verbosity; /* verbosity */ + struct afb_binding_data_v2 *data; /* data */ void *handle; /* context of dlopen */ struct afb_svc *service; /* handler for service started */ struct afb_ditf ditf; /* daemon interface */ @@ -102,8 +102,8 @@ static void call_sync_cb(void *closure, struct afb_xreq *xreq) static int service_start_cb(void *closure, int share_session, int onneed, struct afb_apiset *apiset) { - int (*start)(struct afb_service service); - void (*onevent)(struct afb_service service, const char *event, struct json_object *object); + int (*start)(); + void (*onevent)(const char *event, struct json_object *object); struct api_so_v2 *desc = closure; @@ -120,7 +120,8 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct /* get the initialisation */ start = desc->binding->init; - if (start == NULL) { + onevent = desc->binding->onevent; + if (start == NULL && onevent == NULL) { /* not an error when onneed */ if (onneed != 0) return 0; @@ -131,8 +132,7 @@ static int service_start_cb(void *closure, int share_session, int onneed, struct } /* get the event handler if any */ - onevent = desc->binding->onevent; - desc->service = afb_svc_create_v2(apiset, share_session, start, onevent, &desc->ditf); + desc->service = afb_svc_create_v2(apiset, share_session, start, onevent, desc->data); if (desc->service == NULL) { /* starting error */ ERROR("Starting service %s failed", desc->binding->api); @@ -151,19 +151,108 @@ static void update_hooks_cb(void *closure) static int get_verbosity_cb(void *closure) { struct api_so_v2 *desc = closure; - return *desc->verbosity; + return desc->data->verbosity; } static void set_verbosity_cb(void *closure, int level) { struct api_so_v2 *desc = closure; - *desc->verbosity = level; + desc->data->verbosity = level; +} + +static struct json_object *addperm(struct json_object *o, struct json_object *x) +{ + struct json_object *a; + + if (!o) + return x; + + if (!json_object_object_get_ex(o, "allOf", &a)) { + a = json_object_new_array(); + json_object_array_add(a, o); + o = json_object_new_object(); + json_object_object_add(o, "allOf", a); + } + json_object_array_add(a, x); + return o; +} + +static struct json_object *addperm_key_val(struct json_object *o, const char *key, struct json_object *val) +{ + struct json_object *x = json_object_new_object(); + json_object_object_add(x, key, val); + return addperm(o, x); +} + +static struct json_object *addperm_key_valstr(struct json_object *o, const char *key, const char *val) +{ + return addperm_key_val(o, key, json_object_new_string(val)); +} + +static struct json_object *addperm_key_valint(struct json_object *o, const char *key, int val) +{ + return addperm_key_val(o, key, json_object_new_int(val)); +} + +static struct json_object *make_description(struct api_so_v2 *desc) +{ + char buffer[256]; + const struct afb_verb_v2 *verb; + struct json_object *r, *f, *a, *i, *p, *g; + + r = json_object_new_object(); + json_object_object_add(r, "openapi", json_object_new_string("3.0.0")); + + i = json_object_new_object(); + json_object_object_add(r, "info", i); + json_object_object_add(i, "title", json_object_new_string(desc->binding->api)); + json_object_object_add(i, "version", json_object_new_string("0.0.0")); + + p = json_object_new_object(); + json_object_object_add(r, "paths", p); + verb = desc->binding->verbs; + while (verb->verb) { + buffer[0] = '/'; + strncpy(buffer + 1, verb->verb, sizeof buffer - 1); + buffer[sizeof buffer - 1] = 0; + f = json_object_new_object(); + json_object_object_add(p, buffer, f); + g = json_object_new_object(); + json_object_object_add(f, "get", g); + + a = NULL; + if (verb->session & AFB_SESSION_CLOSE_V2) + a = addperm_key_valstr(a, "session", "close"); + if (verb->session & AFB_SESSION_CHECK_V2) + a = addperm_key_valstr(a, "session", "check"); + if (verb->session & AFB_SESSION_REFRESH_V2) + a = addperm_key_valstr(a, "token", "refresh"); + if (verb->session & AFB_SESSION_LOA_MASK_V2) + a = addperm_key_valint(a, "LOA", verb->session & AFB_SESSION_LOA_MASK_V2); +#if 0 + if (verb->auth) + a = +#endif + if (a) + json_object_object_add(g, "x-permissions", a); + + a = json_object_new_object(); + json_object_object_add(g, "responses", a); + f = json_object_new_object(); + json_object_object_add(a, "200", f); + json_object_object_add(f, "description", json_object_new_string(verb->verb)); + verb++; + } + return r; } static struct json_object *describe_cb(void *closure) { struct api_so_v2 *desc = closure; - return desc->binding->specification ? json_tokener_parse(desc->binding->specification) : NULL; + struct json_object *r = desc->binding->specification ? json_tokener_parse(desc->binding->specification) : NULL; + if (!r) + r = make_description(desc); + return r; } static struct afb_api_itf so_v2_api_itf = { @@ -184,36 +273,37 @@ static struct afb_api_itf so_v2_sync_api_itf = { .describe = describe_cb }; -int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle, struct afb_apiset *apiset, int *pver) +int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle, struct afb_apiset *apiset, struct afb_binding_data_v2 *data) { int rc; struct api_so_v2 *desc; struct afb_api afb_api; /* basic checks */ + assert(binding); assert(binding->api); - assert(binding->specification); assert(binding->verbs); + assert(data); /* allocates the description */ - desc = malloc(sizeof *desc); + desc = calloc(1, sizeof *desc); if (desc == NULL) { ERROR("out of memory"); goto error; } desc->binding = binding; - desc->verbosity = pver; + desc->data = data; desc->handle = handle; desc->service = NULL; - memset(&desc->ditf, 0, sizeof desc->ditf); /* init the interface */ - afb_ditf_init_v2(&desc->ditf, binding->api); + desc->data->verbosity = verbosity; + afb_ditf_init_v2(&desc->ditf, binding->api, data); /* init the binding */ if (binding->preinit) { INFO("binding %s calling preinit function", binding->api); - rc = binding->preinit(desc->ditf.daemon); + rc = binding->preinit(); if (rc < 0) { ERROR("binding %s preinit function failed...", binding->api); goto error2; @@ -222,7 +312,7 @@ int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle /* records the binding */ afb_api.closure = desc; - afb_api.itf = binding->concurrent ? &so_v2_api_itf : &so_v2_sync_api_itf; + afb_api.itf = binding->noconcurrency ? &so_v2_sync_api_itf : &so_v2_api_itf; if (afb_apiset_add(apiset, binding->api, afb_api) < 0) { ERROR("binding %s can't be registered to set %s...", binding->api, afb_apiset_name(apiset)); goto error2; @@ -239,19 +329,20 @@ error: int afb_api_so_v2_add(const char *path, void *handle, struct afb_apiset *apiset) { const struct afb_binding_v2 *binding; - int *pver; + struct afb_binding_data_v2 *data; /* retrieves the register function */ binding = dlsym(handle, afb_api_so_v2_descriptor); - pver = dlsym(handle, afb_api_so_v2_verbosity); - if (!binding && !pver) + data = dlsym(handle, afb_api_so_v2_data); + if (!binding && !data) return 0; INFO("binding [%s] looks like an AFB binding V2", path); /* basic checks */ - if (!binding || !pver) { - ERROR("binding [%s] incomplete symbols...", path); + if (!binding || !data) { + ERROR("binding [%s] incomplete symbol set: %s is missing", + path, binding ? afb_api_so_v2_data : afb_api_so_v2_descriptor); goto error; } if (binding->api == NULL || *binding->api == 0) { @@ -262,16 +353,18 @@ int afb_api_so_v2_add(const char *path, void *handle, struct afb_apiset *apiset) ERROR("binding [%s] invalid api name...", path); goto error; } +#if 0 if (binding->specification == NULL || *binding->specification == 0) { ERROR("binding [%s] bad specification...", path); goto error; } +#endif if (binding->verbs == NULL) { ERROR("binding [%s] no verbs...", path); goto error; } - return afb_api_so_v2_add_binding(binding, handle, apiset, pver); + return afb_api_so_v2_add_binding(binding, handle, apiset, data); error: return -1; diff --git a/src/afb-api-so-v2.h b/src/afb-api-so-v2.h index b60ebe66..82600fa4 100644 --- a/src/afb-api-so-v2.h +++ b/src/afb-api-so-v2.h @@ -20,6 +20,7 @@ struct afb_apiset; struct afb_binding_v2; +struct afb_binding_data_v2; extern int afb_api_so_v2_add(const char *path, void *handle, struct afb_apiset *apiset); -extern int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle, struct afb_apiset *apiset, int *verbosity); +extern int afb_api_so_v2_add_binding(const struct afb_binding_v2 *binding, void *handle, struct afb_apiset *apiset, struct afb_binding_data_v2 *data); diff --git a/src/afb-api-so.c b/src/afb-api-so.c index b5da60f5..bee5fe80 100644 --- a/src/afb-api-so.c +++ b/src/afb-api-so.c @@ -45,26 +45,29 @@ static int load_binding(const char *path, int force, struct afb_apiset *apiset) goto error; } - /* retrieves the register function */ + /* try the version 2 */ rc = afb_api_so_v2_add(path, handle, apiset); if (rc < 0) { /* error when loading a valid v2 binding */ goto error2; } + if (rc) + return 0; /* yes version 2 */ + + /* try the version 1 */ rc = afb_api_so_v1_add(path, handle, apiset); if (rc < 0) { /* error when loading a valid v1 binding */ goto error2; } - if (rc == 0) { - /* not a v1 binding */ - if (force) - ERROR("binding [%s] is not an AFB binding", path); - else - INFO("binding [%s] is not an AFB binding", path); - goto error2; - } - return 0; + if (rc) + return 0; /* yes version 1 */ + + /* not a valid binding */ + if (force) + ERROR("binding [%s] is not an AFB binding", path); + else + INFO("binding [%s] is not an AFB binding", path); error2: dlclose(handle); diff --git a/src/afb-ditf.c b/src/afb-ditf.c index e6b6857c..474c58cf 100644 --- a/src/afb-ditf.c +++ b/src/afb-ditf.c @@ -16,14 +16,14 @@ */ #define _GNU_SOURCE -#define AFB_BINDING_PRAGMA_NO_VERBOSE_MACRO #include #include #include -#include +#include +#include #include "afb-ditf.h" #include "afb-evt.h" @@ -176,7 +176,8 @@ static int hooked_queue_job_cb(void *closure, void (*callback)(int signum, void } static const struct afb_daemon_itf daemon_itf = { - .vverbose = old_vverbose_cb, + .vverbose_v1 = old_vverbose_cb, + .vverbose_v2 = vverbose_cb, .event_make = event_make_cb, .event_broadcast = event_broadcast_cb, .get_event_loop = afb_common_get_event_loop, @@ -188,7 +189,8 @@ static const struct afb_daemon_itf daemon_itf = { }; static const struct afb_daemon_itf hooked_daemon_itf = { - .vverbose = hooked_old_vverbose_cb, + .vverbose_v1 = hooked_old_vverbose_cb, + .vverbose_v2 = hooked_vverbose_cb, .event_make = hooked_event_make_cb, .event_broadcast = hooked_event_broadcast_cb, .get_event_loop = hooked_get_event_loop, @@ -199,19 +201,21 @@ static const struct afb_daemon_itf hooked_daemon_itf = { .queue_job = hooked_queue_job_cb }; -void afb_ditf_init_v2(struct afb_ditf *ditf, const char *prefix) +void afb_ditf_init_v2(struct afb_ditf *ditf, const char *prefix, struct afb_binding_data_v2 *data) { ditf->version = 2; - ditf->daemon.closure = ditf; + ditf->v2 = data; + data->daemon.closure = ditf; afb_ditf_rename(ditf, prefix); } -void afb_ditf_init_v1(struct afb_ditf *ditf, const char *prefix) +void afb_ditf_init_v1(struct afb_ditf *ditf, const char *prefix, struct afb_binding_interface_v1 *itf) { ditf->version = 1; - ditf->interface.verbosity = verbosity; - ditf->interface.mode = AFB_MODE_LOCAL; - ditf->interface.daemon.closure = ditf; + ditf->v1 = itf; + itf->verbosity = verbosity; + itf->mode = AFB_MODE_LOCAL; + itf->daemon.closure = ditf; afb_ditf_rename(ditf, prefix); } @@ -226,11 +230,11 @@ void afb_ditf_update_hook(struct afb_ditf *ditf) int hooked = !!afb_hook_flags_ditf(ditf->prefix); switch (ditf->version) { case 1: - ditf->interface.daemon.itf = hooked ? &hooked_daemon_itf : &daemon_itf; + ditf->v1->daemon.itf = hooked ? &hooked_daemon_itf : &daemon_itf; break; default: case 2: - ditf->daemon.itf = hooked ? &hooked_daemon_itf : &daemon_itf; + ditf->v2->daemon.itf = hooked ? &hooked_daemon_itf : &daemon_itf; break; } } diff --git a/src/afb-ditf.h b/src/afb-ditf.h index 2af76d28..6bc84986 100644 --- a/src/afb-ditf.h +++ b/src/afb-ditf.h @@ -15,36 +15,23 @@ * limitations under the License. */ -#define _GNU_SOURCE -#define AFB_BINDING_PRAGMA_NO_VERBOSE_MACRO - -#include -#include -#include - -#include - -#include "afb-svc.h" -#include "afb-evt.h" -#include "afb-common.h" -#include "afb-context.h" -#include "afb-api-so.h" -#include "afb-xreq.h" -#include "verbose.h" +#pragma once +struct afb_binding_interface_v1; +struct afb_binding_data_v2; struct afb_ditf { int version; const char *prefix; union { - struct afb_binding_interface_v1 interface; - struct afb_daemon daemon; + struct afb_binding_interface_v1 *v1; + struct afb_binding_data_v2 *v2; }; }; -extern void afb_ditf_init_v1(struct afb_ditf *ditf, const char *prefix); -extern void afb_ditf_init_v2(struct afb_ditf *ditf, const char *prefix); +extern void afb_ditf_init_v1(struct afb_ditf *ditf, const char *prefix, struct afb_binding_interface_v1 *itf); +extern void afb_ditf_init_v2(struct afb_ditf *ditf, const char *prefix, struct afb_binding_data_v2 *data); extern void afb_ditf_rename(struct afb_ditf *ditf, const char *prefix); extern void afb_ditf_update_hook(struct afb_ditf *ditf); diff --git a/src/afb-monitor.c b/src/afb-monitor.c index a0618113..35d0e150 100644 --- a/src/afb-monitor.c +++ b/src/afb-monitor.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include "afb-api.h" #include "afb-apiset.h" @@ -34,10 +34,11 @@ extern struct afb_apiset *main_apiset; +static struct afb_binding_data_v2 datav2; + int afb_monitor_init() { - static int v; - return afb_api_so_v2_add_binding(&_afb_binding_v2_monitor, NULL, main_apiset, &v); + return afb_api_so_v2_add_binding(&_afb_binding_v2_monitor, NULL, main_apiset, &datav2); } /****************************************************************************** @@ -213,6 +214,8 @@ static void get_verbosity(struct json_object *resu, struct json_object *spec) n = json_object_array_length(spec); for (i = 0 ; i < n ; i++) get_verbosity_of(resu, json_object_get_string(json_object_array_get_idx(spec, i))); + } else if (json_object_is_type(spec, json_type_string)) { + get_verbosity_of(resu, json_object_get_string(spec)); } else if (json_object_get_boolean(spec)) { get_verbosity_of(resu, ""); get_verbosity_of(resu, "*"); @@ -274,6 +277,8 @@ static void get_apis(struct json_object *resu, struct json_object *spec) n = json_object_array_length(spec); for (i = 0 ; i < n ; i++) get_one_api(resu, json_object_get_string(json_object_array_get_idx(spec, i)), NULL); + } else if (json_object_is_type(spec, json_type_string)) { + get_one_api(resu, json_object_get_string(spec), NULL); } else if (json_object_get_boolean(spec)) { afb_apiset_enum(main_apiset, get_apis_of_all_cb, resu); } diff --git a/src/afb-svc.c b/src/afb-svc.c index 57173412..8976dc6c 100644 --- a/src/afb-svc.c +++ b/src/afb-svc.c @@ -22,8 +22,8 @@ #include -#include -#include +#include +#include #include "afb-session.h" #include "afb-context.h" @@ -33,7 +33,6 @@ #include "afb-xreq.h" #include "afb-cred.h" #include "afb-apiset.h" -#include "afb-ditf.h" #include "verbose.h" /* @@ -51,13 +50,9 @@ struct afb_svc struct afb_evt_listener *listener; /* on event callback for the service */ - union { - void (*on_event_v1)(const char *event, struct json_object *object); - void (*on_event_v2)(struct afb_service service, const char *event, struct json_object *object); - }; + void (*on_event)(const char *event, struct json_object *object); - /* the daemon interface */ - struct afb_ditf *ditf; + struct afb_binding_data_v2 *v2; }; /* @@ -73,8 +68,7 @@ struct svc_req }; /* functions for services */ -static void svc_on_event_v1(void *closure, const char *event, int eventid, struct json_object *object); -static void svc_on_event_v2(void *closure, const char *event, int eventid, struct json_object *object); +static void svc_on_event(void *closure, const char *event, int eventid, struct json_object *object); static void svc_call(void *closure, const char *api, const char *verb, struct json_object *args, void (*callback)(void*, int, struct json_object*), void *cbclosure); @@ -84,13 +78,9 @@ static const struct afb_service_itf service_itf = { }; /* the interface for events */ -static const struct afb_evt_itf evt_itf_v1 = { - .broadcast = svc_on_event_v1, - .push = svc_on_event_v1 -}; -static const struct afb_evt_itf evt_itf_v2 = { - .broadcast = svc_on_event_v2, - .push = svc_on_event_v2 +static const struct afb_evt_itf evt_itf = { + .broadcast = svc_on_event, + .push = svc_on_event }; /* functions for requests of services */ @@ -192,8 +182,8 @@ struct afb_svc *afb_svc_create_v1( /* initialises the listener if needed */ if (on_event) { - svc->on_event_v1 = on_event; - svc->listener = afb_evt_listener_create(&evt_itf_v1, svc); + svc->on_event = on_event; + svc->listener = afb_evt_listener_create(&evt_itf, svc); if (svc->listener == NULL) goto error; } @@ -216,9 +206,9 @@ error: struct afb_svc *afb_svc_create_v2( struct afb_apiset *apiset, int share_session, - int (*start)(struct afb_service service), - void (*on_event)(struct afb_service service, const char *event, struct json_object *object), - struct afb_ditf *ditf + int (*start)(), + void (*on_event)(const char *event, struct json_object *object), + struct afb_binding_data_v2 *data ) { int rc; @@ -228,20 +218,23 @@ struct afb_svc *afb_svc_create_v2( svc = afb_svc_alloc(apiset, share_session); if (svc == NULL) goto error; - svc->ditf = ditf; + svc->v2 = data; + data->service = to_afb_service_v2(svc); /* initialises the listener if needed */ if (on_event) { - svc->on_event_v2 = on_event; - svc->listener = afb_evt_listener_create(&evt_itf_v2, svc); + svc->on_event = on_event; + svc->listener = afb_evt_listener_create(&evt_itf, svc); if (svc->listener == NULL) goto error; } - /* initialises the svc now */ - rc = start(to_afb_service_v2(svc)); - if (rc < 0) - goto error; + /* starts the svc if needed */ + if (start) { + rc = start(); + if (rc < 0) + goto error; + } return svc; @@ -253,20 +246,10 @@ error: /* * Propagates the event to the service */ -static void svc_on_event_v1(void *closure, const char *event, int eventid, struct json_object *object) -{ - struct afb_svc *svc = closure; - svc->on_event_v1(event, object); - json_object_put(object); -} - -/* - * Propagates the event to the service - */ -static void svc_on_event_v2(void *closure, const char *event, int eventid, struct json_object *object) +static void svc_on_event(void *closure, const char *event, int eventid, struct json_object *object) { struct afb_svc *svc = closure; - svc->on_event_v2(to_afb_service_v2(svc), event, object); + svc->on_event(event, object); json_object_put(object); } diff --git a/src/afb-svc.h b/src/afb-svc.h index 62b329df..347716d2 100644 --- a/src/afb-svc.h +++ b/src/afb-svc.h @@ -20,7 +20,7 @@ struct afb_svc; struct afb_service; struct afb_apiset; -struct afb_ditf; +struct afb_binding_data_v2; extern struct afb_svc *afb_svc_create_v1( struct afb_apiset *apiset, @@ -31,6 +31,6 @@ extern struct afb_svc *afb_svc_create_v1( extern struct afb_svc *afb_svc_create_v2( struct afb_apiset *apiset, int share_session, - int (*start)(struct afb_service service), - void (*on_event)(struct afb_service service, const char *event, struct json_object *object), - struct afb_ditf *ditf); + int (*start)(), + void (*on_event)(const char *event, struct json_object *object), + struct afb_binding_data_v2 *data); diff --git a/src/genskel/genskel.c b/src/genskel/genskel.c index 58f7a2c4..8afb70b6 100644 --- a/src/genskel/genskel.c +++ b/src/genskel/genskel.c @@ -72,7 +72,7 @@ const char *scope = NULL; const char *prefix = NULL; const char *postfix = NULL; int priv = -1; -int conc = -1; +int noconc = -1; /** * Search for a reference of type "#/a/b/c" int the @@ -594,7 +594,7 @@ void process(char *filename) getvar(&prefix, "#/info/x-binding-c-generator/prefix", "afb_verb_"); getvar(&postfix, "#/info/x-binding-c-generator/postfix", "_cb"); getvarbool(&priv, "#/info/x-binding-c-generator/private", 0); - getvarbool(&conc, "#/info/x-binding-c-generator/concurrent", 0); + getvarbool(&noconc, "#/info/x-binding-c-generator/noconcurrency", 0); getvar(&api, "#/info/title", "?"); /* get the API name */ @@ -628,7 +628,7 @@ void process(char *filename) " .preinit = %s,\n" " .init = %s,\n" " .onevent = %s,\n" - " .concurrent = %d\n" + " .noconcurrency = %d\n" "};\n" "\n" , priv ? "static " : "" @@ -640,7 +640,7 @@ void process(char *filename) , preinit ?: "NULL" , init ?: "NULL" , onevent ?: "NULL" - , !!conc + , !!noconc ); /* clean up */ diff --git a/src/verbose.c b/src/verbose.c index 88183c27..5b2611a7 100644 --- a/src/verbose.c +++ b/src/verbose.c @@ -99,7 +99,7 @@ void vverbose(int level, const char *file, int line, const char *function, const fprintf(stderr, "%s: ", prefixes[LEVEL(level)] + (tty ? 4 : 0)); vfprintf(stderr, fmt, args); - if (file != NULL && (!tty || verbosity >5)) + if (file != NULL && (!tty || verbosity > 2)) fprintf(stderr, " [%s:%d,%s]\n", file, line, function); else fprintf(stderr, "\n"); -- 2.16.6