Add a closure argument to dynamic verbs
[src/app-framework-binder.git] / include / afb / afb-dynapi.h
1 /*
2  * Copyright (C) 2016, 2017 "IoT.bzh"
3  * Author: José Bollo <jose.bollo@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #pragma once
19
20 #include "afb-dynapi-itf.h"
21
22 /*
23  * Send a message described by 'fmt' and following parameters
24  * to the journal for the verbosity 'level'.
25  *
26  * 'file', 'line' and 'func' are indicators of position of the code in source files
27  * (see macros __FILE__, __LINE__ and __func__).
28  *
29  *
30  * 'level' is defined by syslog standard:
31  *      EMERGENCY         0        System is unusable
32  *      ALERT             1        Action must be taken immediately
33  *      CRITICAL          2        Critical conditions
34  *      ERROR             3        Error conditions
35  *      WARNING           4        Warning conditions
36  *      NOTICE            5        Normal but significant condition
37  *      INFO              6        Informational
38  *      DEBUG             7        Debug-level messages
39  */
40 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)));
41 static inline void afb_dynapi_verbose(struct afb_dynapi *dynapi, int level, const char *file, int line, const char *func, const char *fmt, ...)
42 {
43         va_list args;
44         va_start(args, fmt);
45         dynapi->itf->vverbose(dynapi, level, file, line, func, fmt, args);
46         va_end(args);
47 }
48 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)
49 {
50         dynapi->itf->vverbose(dynapi, level, file, line, func, fmt, args);
51 }
52
53 /*
54  * Retrieves the common systemd's event loop of AFB
55  */
56 static inline struct sd_event *afb_dynapi_get_event_loop(struct afb_dynapi *dynapi)
57 {
58         return dynapi->itf->get_event_loop(dynapi);
59 }
60
61 /*
62  * Retrieves the common systemd's user/session d-bus of AFB
63  */
64 static inline struct sd_bus *afb_dynapi_get_user_bus(struct afb_dynapi *dynapi)
65 {
66         return dynapi->itf->get_user_bus(dynapi);
67 }
68
69 /*
70  * Retrieves the common systemd's system d-bus of AFB
71  */
72 static inline struct sd_bus *afb_dynapi_get_system_bus(struct afb_dynapi *dynapi)
73 {
74         return dynapi->itf->get_system_bus(dynapi);
75 }
76
77 /*
78  * Get the root directory file descriptor. This file descriptor can
79  * be used with functions 'openat', 'fstatat', ...
80  */
81 static inline int afb_dynapi_rootdir_get_fd(struct afb_dynapi *dynapi)
82 {
83         return dynapi->itf->rootdir_get_fd(dynapi);
84 }
85
86 /*
87  * Opens 'filename' within the root directory with 'flags' (see function openat)
88  * using the 'locale' definition (example: "jp,en-US") that can be NULL.
89  * Returns the file descriptor or -1 in case of error.
90  */
91 static inline int afb_dynapi_rootdir_open_locale(struct afb_dynapi *dynapi, const char *filename, int flags, const char *locale)
92 {
93         return dynapi->itf->rootdir_open_locale(dynapi, filename, flags, locale);
94 }
95
96 /*
97  * Queue the job defined by 'callback' and 'argument' for being executed asynchronously
98  * in this thread (later) or in an other thread.
99  * If 'group' is not NUL, the jobs queued with a same value (as the pointer value 'group')
100  * are executed in sequence in the order of there submission.
101  * If 'timeout' is not 0, it represent the maximum execution time for the job in seconds.
102  * At first, the job is called with 0 as signum and the given argument.
103  * The job is executed with the monitoring of its time and some signals like SIGSEGV and
104  * SIGFPE. When a such signal is catched, the job is terminated and reexecuted but with
105  * signum being the signal number (SIGALRM when timeout expired).
106  *
107  * Returns 0 in case of success or -1 in case of error.
108  */
109 static inline int afb_dynapi_queue_job(struct afb_dynapi *dynapi, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
110 {
111         return dynapi->itf->queue_job(dynapi, callback, argument, group, timeout);
112 }
113
114 /*
115  * Tells that it requires the API of "name" to exist
116  * and if 'initialized' is not null to be initialized.
117  * Calling this function is only allowed within init.
118  * Returns 0 in case of success or -1 in case of error.
119  */
120 static inline int afb_dynapi_require_api(struct afb_dynapi *dynapi, const char *name, int initialized)
121 {
122         return dynapi->itf->require_api(dynapi, name, initialized);
123 }
124
125 /*
126  * Set the name of the API to 'name'.
127  * Calling this function is only allowed within preinit.
128  * Returns 0 in case of success or -1 in case of error.
129  */
130 static inline int afb_dynapi_rename_api(struct afb_dynapi *dynapi, const char *name)
131 {
132         return dynapi->itf->rename_api(dynapi, name);
133 }
134
135 /*
136  * Broadcasts widely the event of 'name' with the data 'object'.
137  * 'object' can be NULL.
138  *
139  * For convenience, the function calls 'json_object_put' for 'object'.
140  * Thus, in the case where 'object' should remain available after
141  * the function returns, the function 'json_object_get' shall be used.
142  *
143  * Calling this function is only forbidden during preinit.
144  *
145  * Returns the count of clients that received the event.
146  */
147 static inline int afb_dynapi_broadcast_event(struct afb_dynapi *dynapi, const char *name, struct json_object *object)
148 {
149         return dynapi->itf->event_broadcast(dynapi, name, object);
150 }
151
152 /*
153  * Creates an event of 'name' and returns it.
154  *
155  * Calling this function is only forbidden during preinit.
156  *
157  * See afb_event_is_valid to check if there is an error.
158  */
159 static inline struct afb_eventid *afb_dynapi_make_eventid(struct afb_dynapi *dynapi, const char *name)
160 {
161         return dynapi->itf->eventid_make(dynapi, name);
162 }
163
164 /**
165  * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
166  * The result of the call is delivered to the 'callback' function with the 'callback_closure'.
167  *
168  * For convenience, the function calls 'json_object_put' for 'args'.
169  * Thus, in the case where 'args' should remain available after
170  * the function returns, the function 'json_object_get' shall be used.
171  *
172  * The 'callback' receives 3 arguments:
173  *  1. 'closure' the user defined closure pointer 'callback_closure',
174  *  2. 'status' a status being 0 on success or negative when an error occured,
175  *  2. 'result' the resulting data as a JSON object.
176  *
177  * @param dynapi   The dynapi
178  * @param api      The api name of the method to call
179  * @param verb     The verb name of the method to call
180  * @param args     The arguments to pass to the method
181  * @param callback The to call on completion
182  * @param callback_closure The closure to pass to the callback
183  *
184  * @see also 'afb_req_subcall'
185  */
186 static inline void afb_dynapi_call(
187         struct afb_dynapi *dynapi,
188         const char *api,
189         const char *verb,
190         struct json_object *args,
191         void (*callback)(void*closure, int status, struct json_object *result, struct afb_dynapi *dynapi),
192         void *callback_closure)
193 {
194         dynapi->itf->call(dynapi, api, verb, args, callback, callback_closure);
195 }
196
197 /**
198  * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
199  * 'result' will receive the response.
200  *
201  * For convenience, the function calls 'json_object_put' for 'args'.
202  * Thus, in the case where 'args' should remain available after
203  * the function returns, the function 'json_object_get' shall be used.
204  *
205  * @param dynapi   The dynapi
206  * @param api      The api name of the method to call
207  * @param verb     The verb name of the method to call
208  * @param args     The arguments to pass to the method
209  * @param result   Where to store the result - should call json_object_put on it -
210  *
211  * @returns 0 in case of success or a negative value in case of error.
212  *
213  * @see also 'afb_req_subcall'
214  */
215 static inline int afb_dynapi_call_sync(
216         struct afb_dynapi *dynapi,
217         const char *api,
218         const char *verb,
219         struct json_object *args,
220         struct json_object **result)
221 {
222         return dynapi->itf->call_sync(dynapi, api, verb, args, result);
223 }
224
225
226 static inline int afb_dynapi_new_api(
227         struct afb_dynapi *dynapi,
228         const char *api,
229         const char *info,
230         int (*preinit)(void*, struct afb_dynapi *),
231         void *closure)
232 {
233         return dynapi->itf->api_new_api(dynapi, api, info, preinit, closure);
234 }
235
236 static inline int afb_dynapi_set_verbs_v2(
237         struct afb_dynapi *dynapi,
238         const struct afb_verb_v2 *verbs)
239 {
240         return dynapi->itf->api_set_verbs_v2(dynapi, verbs);
241 }
242
243 static inline int afb_dynapi_add_verb(
244         struct afb_dynapi *dynapi,
245         const char *verb,
246         const char *info,
247         void (*callback)(struct afb_request *request),
248         void *vcbdata,
249         const struct afb_auth *auth,
250         uint32_t session)
251 {
252         return dynapi->itf->api_add_verb(dynapi, verb, info, callback, vcbdata, auth, session);
253 }
254
255
256 static inline int afb_dynapi_sub_verb(
257                 struct afb_dynapi *dynapi,
258                 const char *verb)
259 {
260         return dynapi->itf->api_sub_verb(dynapi, verb);
261 }
262
263
264 static inline int afb_dynapi_on_event(
265                 struct afb_dynapi *dynapi,
266                 void (*onevent)(struct afb_dynapi *dynapi, const char *event, struct json_object *object))
267 {
268         return dynapi->itf->api_set_on_event(dynapi, onevent);
269 }
270
271
272 static inline int afb_dynapi_on_init(
273                 struct afb_dynapi *dynapi,
274                 int (*oninit)(struct afb_dynapi *dynapi))
275 {
276         return dynapi->itf->api_set_on_init(dynapi, oninit);
277 }
278
279
280 static inline void afb_dynapi_seal(
281                 struct afb_dynapi *dynapi)
282 {
283         dynapi->itf->api_seal(dynapi);
284 }
285
286