2 * Copyright (C) 2016, 2017, 2018 "IoT.bzh"
3 * Author: José Bollo <jose.bollo@iot.bzh>
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "afb-verbosity.h"
21 #include "afb-api-x3-itf.h"
24 * Get the name of the 'api'.
26 * @param api the api whose name is to be returned
28 * @return the name of the api.
30 * The returned value must not be changed nor freed.
33 const char *afb_api_x3_name(struct afb_api_x3 *api)
39 * Get the "userdata" pointer of the 'api'
41 * @param api the api whose user's data is to be returned
43 * @return the user's data pointer of the api.
45 * @see afb_api_x3_set_userdata
48 void *afb_api_x3_get_userdata(struct afb_api_x3 *api)
54 * Set the "userdata" pointer of the 'api' to 'value'
56 * @param api the api whose user's data is to be set
57 * @param value the data to set
59 * @see afb_api_x3_get_userdata
62 void afb_api_x3_set_userdata(struct afb_api_x3 *api, void *value)
64 api->userdata = value;
68 * Is the log message of 'level (as defined for syslog) required for the api?
70 * @param api the api to check
71 * @param level the level to check as defined for syslog:
73 * EMERGENCY 0 System is unusable
74 * ALERT 1 Action must be taken immediately
75 * CRITICAL 2 Critical conditions
76 * ERROR 3 Error conditions
77 * WARNING 4 Warning conditions
78 * NOTICE 5 Normal but significant condition
79 * INFO 6 Informational
80 * DEBUG 7 Debug-level messages
82 * @return 0 if not required or a value not null if required
87 int afb_api_x3_wants_log_level(struct afb_api_x3 *api, int level)
89 return AFB_SYSLOG_MASK_WANT(api->logmask, level);
93 * Send to the journal with the log 'level' a message described
94 * by 'fmt' applied to the va-list 'args'.
96 * 'file', 'line' and 'func' are indicators of position of the code in source files
97 * (see macros __FILE__, __LINE__ and __func__).
99 * 'level' is defined by syslog standard:
101 * EMERGENCY 0 System is unusable
102 * ALERT 1 Action must be taken immediately
103 * CRITICAL 2 Critical conditions
104 * ERROR 3 Error conditions
105 * WARNING 4 Warning conditions
106 * NOTICE 5 Normal but significant condition
107 * INFO 6 Informational
108 * DEBUG 7 Debug-level messages
110 * @param api the api that collects the logging message
111 * @param level the level of the message
112 * @param file the source file that logs the messages or NULL
113 * @param line the line in the source file that logs the message
114 * @param func the name of the function in the source file that logs
115 * @param fmt the format of the message as in printf
116 * @param args the arguments to the format string of the message as a va_list
122 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)
124 api->itf->vverbose(api, level, file, line, func, fmt, args);
128 * Send to the journal with the log 'level' a message described
129 * by 'fmt' and following parameters.
131 * 'file', 'line' and 'func' are indicators of position of the code in source files
132 * (see macros __FILE__, __LINE__ and __func__).
134 * 'level' is defined by syslog standard:
135 * EMERGENCY 0 System is unusable
136 * ALERT 1 Action must be taken immediately
137 * CRITICAL 2 Critical conditions
138 * ERROR 3 Error conditions
139 * WARNING 4 Warning conditions
140 * NOTICE 5 Normal but significant condition
141 * INFO 6 Informational
142 * DEBUG 7 Debug-level messages
144 * @param api the api that collects the logging message
145 * @param level the level of the message
146 * @param file the source file that logs the messages or NULL
147 * @param line the line in the source file that logs the message
148 * @param func the name of the function in the source file that logs
149 * @param fmt the format of the message as in printf
150 * @param ... the arguments to the format string of the message
155 __attribute__((format(printf, 6, 7)))
157 void afb_api_x3_verbose(
158 struct afb_api_x3 *api,
168 api->itf->vverbose(api, level, file, line, func, fmt, args);
173 * Retrieves the common systemd's event loop of AFB
175 * @param api the api that uses the event loop
177 * @return the systemd event loop if active, NULL otherwise
179 * @see afb_api_x3_get_user_bus
180 * @see afb_api_x3_get_system_bus
183 struct sd_event *afb_api_x3_get_event_loop(struct afb_api_x3 *api)
185 return api->itf->get_event_loop(api);
189 * Retrieves the common systemd's user/session d-bus of AFB
191 * @param api the api that uses the user dbus
193 * @return the systemd user connection to dbus if active, NULL otherwise
195 * @see afb_api_x3_get_event_loop
196 * @see afb_api_x3_get_system_bus
199 struct sd_bus *afb_api_x3_get_user_bus(struct afb_api_x3 *api)
201 return api->itf->get_user_bus(api);
205 * Retrieves the common systemd's system d-bus of AFB
207 * @param api the api that uses the system dbus
209 * @return the systemd system connection to dbus if active, NULL otherwise
211 * @see afb_api_x3_get_event_loop
212 * @see afb_api_x3_get_user_bus
216 struct sd_bus *afb_api_x3_get_system_bus(struct afb_api_x3 *api)
218 return api->itf->get_system_bus(api);
222 * Get the root directory file descriptor. This file descriptor can
223 * be used with functions 'openat', 'fstatat', ...
225 * CAUTION, manipulate this this descriptor with care, in particular, don't close
228 * This can be used to get the path of the root directory using:
231 * char buffer[MAX_PATH];
232 * int dirfd = afb_api_x3_rootdir_get_fd(api);
233 * snprintf(buffer, sizeof buffer, "/proc/self/fd/%d", dirfd);
234 * readlink(buffer, buffer, sizeof buffer);
237 * But note that within AGL this is the value given by the environment variable
238 * AFM_APP_INSTALL_DIR.
240 * @param api the api that uses the directory file descriptor
242 * @return the file descriptor of the root directory.
244 * @see afb_api_x3_rootdir_open_locale
247 int afb_api_x3_rootdir_get_fd(struct afb_api_x3 *api)
249 return api->itf->rootdir_get_fd(api);
253 * Opens 'filename' within the root directory with 'flags' (see function openat)
254 * using the 'locale' definition (example: "jp,en-US") that can be NULL.
256 * The filename must be relative to the root of the bindings.
258 * The opening mode must be for read or write but not for O_CREAT.
260 * The definition of locales and of how files are searched can be checked
261 * here: https://www.w3.org/TR/widgets/#folder-based-localization
262 * and https://tools.ietf.org/html/rfc7231#section-5.3.5
264 * @param api the api that queries the file
265 * @param filename the relative path to the file to open
266 * @param flags the flags for opening as for C function 'open'
267 * @param locale string indicating how to search content, can be NULL
269 * @return the file descriptor or -1 in case of error and errno is set with the
273 * @see afb_api_x3_rootdir_get_fd
276 int afb_api_x3_rootdir_open_locale(struct afb_api_x3 *api, const char *filename, int flags, const char *locale)
278 return api->itf->rootdir_open_locale(api, filename, flags, locale);
282 * Queue the job defined by 'callback' and 'argument' for being executed asynchronously
283 * in this thread (later) or in an other thread.
285 * If 'group' is not NULL, the jobs queued with a same value (as the pointer value 'group')
286 * are executed in sequence in the order of there submission.
288 * If 'timeout' is not 0, it represent the maximum execution time for the job in seconds.
289 * At first, the job is called with 0 as signum and the given argument.
291 * The job is executed with the monitoring of its time and some signals like SIGSEGV and
292 * SIGFPE. When a such signal is catched, the job is terminated and reexecuted but with
293 * signum being the signal number (SIGALRM when timeout expired).
295 * When executed, the callback function receives 2 arguments:
297 * - int signum: the signal catched if any or zero at the beginning
298 * - void *arg: the parameter 'argument'
300 * A typical implmentation of the job callback is:
303 * void my_job_cb(int signum, void *arg)
305 * struct myarg_t *myarg = arg;
307 * AFB_API_ERROR(myarg->api, "job interupted with signal %s", strsignal(signum));
309 * really_do_my_job(myarg);
313 * @param api the api that queue the job
314 * @param callback the job as a callback function
315 * @param argument the argument to pass to the queued job
316 * @param group the group of the job, NULL if no group
317 * @param timeout the timeout of execution of the job
319 * @return 0 in case of success or -1 in case of error with errno set appropriately.
322 int afb_api_x3_queue_job(struct afb_api_x3 *api, void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
324 return api->itf->queue_job(api, callback, argument, group, timeout);
328 * Tells that it requires the API of "name" to exist
329 * and if 'initialized' is not null to be initialized.
330 * Calling this function is only allowed within init.
332 * A single request allows to require multiple apis.
334 * @param api the api that requires the other api by its name
335 * @param name a space separated list of the names of the required api
336 * @param initialized if zero, the api is just required to exist. If not zero,
337 * the api is required to exist and to be initialized.
339 * @return 0 in case of success or -1 in case of error with errno set appropriately.
342 int afb_api_x3_require_api(struct afb_api_x3 *api, const char *name, int initialized)
344 return api->itf->require_api(api, name, initialized);
348 * Create an aliased name 'as_name' for the api 'name'.
349 * Calling this function is only allowed within preinit.
351 * @param api the api that requires the aliasing
352 * @param name the api to alias
353 * @param as_name the aliased name of the aliased api
355 * @return 0 in case of success or -1 in case of error with errno set appropriately.
358 int afb_api_x3_add_alias(struct afb_api_x3 *api, const char *name, const char *as_name)
360 return api->itf->add_alias(api, name, as_name);
364 * Broadcasts widely the event of 'name' with the data 'object'.
365 * 'object' can be NULL.
367 * For convenience, the function calls 'json_object_put' for 'object'.
368 * Thus, in the case where 'object' should remain available after
369 * the function returns, the function 'json_object_get' shall be used.
371 * Calling this function is only forbidden during preinit.
373 * The event sent as the name API/name where API is the name of the
376 * @param api the api that broadcast the event
377 * @param name the event name suffix
378 * @param object the object that comes with the event
380 * @return the count of clients that received the event.
383 int afb_api_x3_broadcast_event(struct afb_api_x3 *api, const char *name, struct json_object *object)
385 return api->itf->event_broadcast(api, name, object);
389 * Creates an event of 'name' and returns it.
391 * Calling this function is only forbidden during preinit.
393 * See afb_event_is_valid to check if there is an error.
395 * The event created as the name API/name where API is the name of the
398 * @param api the api that creates the event
399 * @param name the event name suffix
401 * @return the created event. Use the function afb_event_is_valid to check
402 * whether the event is valid (created) or not (error as reported by errno).
404 * @see afb_event_is_valid
407 struct afb_event_x2 *afb_api_x3_make_event_x2(struct afb_api_x3 *api, const char *name)
409 return api->itf->event_make(api, name);
413 * @deprecated try to use @ref afb_api_x3_call instead
415 * * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
416 * The result of the call is delivered to the 'callback' function with the 'callback_closure'.
418 * For convenience, the function calls 'json_object_put' for 'args'.
419 * Thus, in the case where 'args' should remain available after
420 * the function returns, the function 'json_object_get' shall be used.
422 * The 'callback' receives 3 arguments:
423 * 1. 'closure' the user defined closure pointer 'closure',
424 * 2. 'status' a status being 0 on success or negative when an error occurred,
425 * 2. 'result' the resulting data as a JSON object.
428 * @param apiname The api name of the method to call
429 * @param verb The verb name of the method to call
430 * @param args The arguments to pass to the method
431 * @param callback The to call on completion
432 * @param closure The closure to pass to the callback
434 * @see also 'afb_api_call'
435 * @see also 'afb_api_call_sync'
436 * @see also 'afb_api_call_sync_legacy'
437 * @see also 'afb_req_subcall'
438 * @see also 'afb_req_subcall_sync'
441 void afb_api_x3_call_legacy(
442 struct afb_api_x3 *api,
445 struct json_object *args,
446 void (*callback)(void *closure, int status, struct json_object *result, struct afb_api_x3 *api),
449 api->itf->legacy_call(api, apiname, verb, args, callback, closure);
453 * @deprecated try to use @ref afb_api_x3_call_sync instead
455 * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
456 * 'result' will receive the response.
458 * For convenience, the function calls 'json_object_put' for 'args'.
459 * Thus, in the case where 'args' should remain available after
460 * the function returns, the function 'json_object_get' shall be used.
463 * @param apiname The api name of the method to call
464 * @param verb The verb name of the method to call
465 * @param args The arguments to pass to the method
466 * @param result Where to store the result - should call json_object_put on it -
468 * @returns 0 in case of success or a negative value in case of error.
470 * @see also 'afb_api_call'
471 * @see also 'afb_api_call_sync'
472 * @see also 'afb_api_call_legacy'
473 * @see also 'afb_req_subcall'
474 * @see also 'afb_req_subcall_sync'
477 int afb_api_x3_call_sync_legacy(
478 struct afb_api_x3 *api,
481 struct json_object *args,
482 struct json_object **result)
484 return api->itf->legacy_call_sync(api, apiname, verb, args, result);
488 * Creates a new api of name 'apiname' briefly described by 'info' (that can
491 * When the pre-initialization function is given, it is a function that
492 * receives 2 parameters:
494 * - the closure as given in the call
495 * - the created api that can be initialised
497 * This pre-initialization function must return a negative value to abort
498 * the creation of the api. Otherwise, it returns a non-negative value to
501 * @param api the api that creates the other one
502 * @param apiname the name of the new api
503 * @param info the brief description of the new api (can be NULL)
504 * @param noconcurrency zero or not zero whether the new api is reentrant or not
505 * @param preinit the pre-initialization function if any (can be NULL)
506 * @param closure the closure for the pre-initialization \ref preinit
508 * @return 0 in case of success or -1 on failure with errno set
510 * @see afb_api_x3_delete_api
513 struct afb_api_x3 *afb_api_x3_new_api(
514 struct afb_api_x3 *api,
518 int (*preinit)(void*, struct afb_api_x3 *),
521 return api->itf->api_new_api(api, apiname, info, noconcurrency, preinit, closure);
525 * @deprecated use @ref afb_api_x3_set_verbs_v3 instead
527 * Set the verbs of the 'api' using description of verbs of the api v2
529 * @param api the api that will get the verbs
530 * @param verbs the array of verbs to add terminated with an item with name=NULL
532 * @return 0 in case of success or -1 on failure with errno set
535 * @see afb_api_x3_add_verb
536 * @see afb_api_x3_set_verbs_v3
539 int afb_api_x3_set_verbs_v2(
540 struct afb_api_x3 *api,
541 const struct afb_verb_v2 *verbs)
543 return api->itf->api_set_verbs_v2(api, verbs);
547 * Add one verb to the dynamic set of the api
549 * @param api the api to change
550 * @param verb name of the verb
551 * @param info brief description of the verb, can be NULL
552 * @param callback callback function implementing the verb
553 * @param vcbdata data for the verb callback, available through req
554 * @param auth required authorization, can be NULL
555 * @param session authorization and session requirements of the verb
556 * @param glob is the verb glob name
558 * @return 0 in case of success or -1 on failure with errno set
561 * @see afb_api_x3_del_verb
562 * @see afb_api_x3_set_verbs_v3
563 * @see fnmatch for matching names using glob
566 int afb_api_x3_add_verb(
567 struct afb_api_x3 *api,
570 void (*callback)(struct afb_req_x2 *req),
572 const struct afb_auth *auth,
576 return api->itf->api_add_verb(api, verb, info, callback, vcbdata, auth, session, glob);
580 * Delete one verb from the dynamic set of the api
582 * @param api the api to change
583 * @param verb name of the verb to delete
584 * @param vcbdata if not NULL will receive the vcbdata of the deleted verb
586 * @return 0 in case of success or -1 on failure with errno set
588 * @see afb_api_x3_add_verb
591 int afb_api_x3_del_verb(
592 struct afb_api_x3 *api,
596 return api->itf->api_del_verb(api, verb, vcbdata);
600 * Set the callback 'onevent' to process events in the name of the 'api'.
602 * This setting can be done statically using the global variable
605 * This function replace any previously global event callback set.
607 * When an event is received, the callback 'onevent' is called with 3 parameters
609 * - the api that recorded the event handler
610 * - the full name of the event
611 * - the companion JSON object of the event
613 * @param api the api that wants to process events
614 * @param onevent the callback function that will process events (can be NULL
615 * to remove event callback)
617 * @return 0 in case of success or -1 on failure with errno set
620 * @see afb_binding_v3
621 * @see afb_api_x3_event_handler_add
622 * @see afb_api_x3_event_handler_del
625 int afb_api_x3_on_event(
626 struct afb_api_x3 *api,
627 void (*onevent)(struct afb_api_x3 *api, const char *event, struct json_object *object))
629 return api->itf->api_set_on_event(api, onevent);
633 * Set the callback 'oninit' to process initialization of the 'api'.
635 * This setting can be done statically using the global variable
638 * This function replace any previously initialization callback set.
640 * This function is only valid during the pre-initialization stage.
642 * The callback initialization function will receive one argument: the api
645 * @param api the api that wants to process events
646 * @param oninit the callback function that initialize the api
648 * @return 0 in case of success or -1 on failure with errno set
651 * @see afb_binding_v3
654 int afb_api_x3_on_init(
655 struct afb_api_x3 *api,
656 int (*oninit)(struct afb_api_x3 *api))
658 return api->itf->api_set_on_init(api, oninit);
662 * Seal the api. After a call to this function the api can not be modified
665 * @param api the api to be sealed
668 void afb_api_x3_seal(
669 struct afb_api_x3 *api)
671 api->itf->api_seal(api);
675 * Set the verbs of the 'api' using description of verbs of the api v2
677 * @param api the api that will get the verbs
678 * @param verbs the array of verbs to add terminated with an item with name=NULL
680 * @return 0 in case of success or -1 on failure with errno set
683 * @see afb_api_x3_add_verb
684 * @see afb_api_x3_del_verb
687 int afb_api_x3_set_verbs_v3(
688 struct afb_api_x3 *api,
689 const struct afb_verb_v3 *verbs)
691 return api->itf->api_set_verbs_v3(api, verbs);
695 * Add a specific event handler for the api
697 * The handler callback is called when an event matching the given pattern
698 * is received (it is received if broadcasted or after subscription through
699 * a call or a subcall).
701 * The handler callback receive 4 arguments:
703 * - the closure given here
704 * - the event full name
705 * - the companion JSON object of the event
706 * - the api that subscribed the event
708 * @param api the api that creates the handler
709 * @param pattern the global pattern of the event to handle
710 * @param callback the handler callback function
711 * @param closure the closure of the handler
713 * @return 0 in case of success or -1 on failure with errno set
715 * @see afb_api_x3_on_event
716 * @see afb_api_x3_event_handler_del
719 int afb_api_x3_event_handler_add(
720 struct afb_api_x3 *api,
722 void (*callback)(void *, const char*, struct json_object*, struct afb_api_x3*),
725 return api->itf->event_handler_add(api, pattern, callback, closure);
729 * Delete a specific event handler for the api
731 * @param api the api that the handler belongs to
732 * @param pattern the global pattern of the handler to remove
733 * @param closure if not NULL it will receive the closure set to the handler
735 * @return 0 in case of success or -1 on failure with errno set
737 * @see afb_api_x3_on_event
738 * @see afb_api_x3_event_handler_add
741 int afb_api_x3_event_handler_del(
742 struct afb_api_x3 *api,
746 return api->itf->event_handler_del(api, pattern, closure);
750 * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
751 * The result of the call is delivered to the 'callback' function with the 'callback_closure'.
753 * For convenience, the function calls 'json_object_put' for 'args'.
754 * Thus, in the case where 'args' should remain available after
755 * the function returns, the function 'json_object_get' shall be used.
757 * The 'callback' receives 5 arguments:
758 * 1. 'closure' the user defined closure pointer 'closure',
759 * 2. 'object' a JSON object returned (can be NULL)
760 * 3. 'error' a string not NULL in case of error but NULL on success
761 * 4. 'info' a string handling some info (can be NULL)
764 * @param api The api that makes the call
765 * @param apiname The api name of the method to call
766 * @param verb The verb name of the method to call
767 * @param args The arguments to pass to the method
768 * @param callback The to call on completion
769 * @param closure The closure to pass to the callback
772 * @see afb_req_subcall
773 * @see afb_req_subcall_sync
774 * @see afb_api_x3_call_sync
777 void afb_api_x3_call(
778 struct afb_api_x3 *api,
781 struct json_object *args,
782 void (*callback)(void *closure, struct json_object *object, const char *error, const char * info, struct afb_api_x3 *api),
785 api->itf->call(api, apiname, verb, args, callback, closure);
789 * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
790 * 'result' will receive the response.
792 * For convenience, the function calls 'json_object_put' for 'args'.
793 * Thus, in the case where 'args' should remain available after
794 * the function returns, the function 'json_object_get' shall be used.
796 * @param api The api that makes the call
797 * @param apiname The api name of the method to call
798 * @param verb The verb name of the method to call
799 * @param args The arguments to pass to the method
800 * @param object Where to store the returned object - should call json_object_put on it - can be NULL
801 * @param error Where to store the copied returned error - should call free on it - can be NULL
802 * @param info Where to store the copied returned info - should call free on it - can be NULL
804 * @returns 0 in case of success or a negative value in case of error.
806 * @see afb_req_subcall
807 * @see afb_req_subcall_sync
808 * @see afb_api_x3_call
811 int afb_api_x3_call_sync(
812 struct afb_api_x3 *api,
815 struct json_object *args,
816 struct json_object **object,
820 return api->itf->call_sync(api, apiname, verb, args, object, error, info);
824 * Tells that the api provides a class of features. Classes are intended to
825 * allow ordering of initializations: apis that provides a given class are
826 * initialized before apis requiring it.
828 * This function is only valid during the pre-initialization stage.
830 * @param api the api that provides the classes
831 * @param name a space separated list of the names of the provided classes
833 * @returns 0 in case of success or a negative value in case of error.
835 * @see afb_api_x3_require_class
838 int afb_api_x3_provide_class(
839 struct afb_api_x3 *api,
842 return api->itf->class_provide(api, name);
846 * Tells that the api requires a set of class features. Classes are intended to
847 * allow ordering of initializations: apis that provides a given class are
848 * initialized before apis requiring it.
850 * This function is only valid during the pre-initialization stage.
852 * @param api the api that requires the classes
853 * @param name a space separated list of the names of the requireded classes
855 * @returns 0 in case of success or a negative value in case of error.
857 * @see afb_api_x3_provide_class
860 int afb_api_x3_require_class(
861 struct afb_api_x3 *api,
864 return api->itf->class_require(api, name);
868 * Delete the given api.
870 * It is of the responsibility of the caller to don't used the deleted api
871 * anymore after this function returned.
873 * @param api the api to delete
875 * @returns 0 in case of success or a negative value in case of error.
877 * @see afb_api_x3_new_api
880 int afb_api_x3_delete_api(
881 struct afb_api_x3 *api)
883 return api->itf->delete_api(api);