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"
27 * Get the name of the 'api'.
29 * @param api the api whose name is to be returned
31 * @return the name of the api.
33 * The returned value must not be changed nor freed.
36 const char *afb_api_x3_name(
37 struct afb_api_x3 *api)
43 * Get the "userdata" pointer of the 'api'
45 * @param api the api whose user's data is to be returned
47 * @return the user's data pointer of the api.
49 * @see afb_api_x3_set_userdata
52 void *afb_api_x3_get_userdata(
53 struct afb_api_x3 *api)
59 * Set the "userdata" pointer of the 'api' to 'value'
61 * @param api the api whose user's data is to be set
62 * @param value the data to set
64 * @see afb_api_x3_get_userdata
67 void afb_api_x3_set_userdata(
68 struct afb_api_x3 *api,
71 api->userdata = value;
75 * Is the log message of 'level (as defined for syslog) required for the api?
77 * @param api the api to check
78 * @param level the level to check as defined for syslog:
80 * EMERGENCY 0 System is unusable
81 * ALERT 1 Action must be taken immediately
82 * CRITICAL 2 Critical conditions
83 * ERROR 3 Error conditions
84 * WARNING 4 Warning conditions
85 * NOTICE 5 Normal but significant condition
86 * INFO 6 Informational
87 * DEBUG 7 Debug-level messages
89 * @return 0 if not required or a value not null if required
94 int afb_api_x3_wants_log_level(
95 struct afb_api_x3 *api,
98 return AFB_SYSLOG_MASK_WANT(api->logmask, level);
102 * Send to the journal with the logging 'level' a message described
103 * by 'fmt' applied to the va-list 'args'.
105 * 'file', 'line' and 'func' are indicators of code position in source files
106 * (see macros __FILE__, __LINE__ and __func__).
108 * 'level' is defined by syslog standard:
110 * EMERGENCY 0 System is unusable
111 * ALERT 1 Action must be taken immediately
112 * CRITICAL 2 Critical conditions
113 * ERROR 3 Error conditions
114 * WARNING 4 Warning conditions
115 * NOTICE 5 Normal but significant condition
116 * INFO 6 Informational
117 * DEBUG 7 Debug-level messages
119 * @param api the api that collects the logging message
120 * @param level the level of the message
121 * @param file the source file that logs the messages or NULL
122 * @param line the line in the source file that logs the message
123 * @param func the name of the function in the source file that logs (or NULL)
124 * @param fmt the format of the message as in printf
125 * @param args the arguments to the format string of the message as a va_list
131 void afb_api_x3_vverbose(
132 struct afb_api_x3 *api,
140 api->itf->vverbose(api, level, file, line, func, fmt, args);
144 * Send to the journal with the log 'level' a message described
145 * by 'fmt' and following parameters.
147 * 'file', 'line' and 'func' are indicators of position of the code in source files
148 * (see macros __FILE__, __LINE__ and __func__).
150 * 'level' is defined by syslog standard:
151 * EMERGENCY 0 System is unusable
152 * ALERT 1 Action must be taken immediately
153 * CRITICAL 2 Critical conditions
154 * ERROR 3 Error conditions
155 * WARNING 4 Warning conditions
156 * NOTICE 5 Normal but significant condition
157 * INFO 6 Informational
158 * DEBUG 7 Debug-level messages
160 * @param api the api that collects the logging message
161 * @param level the level of the message
162 * @param file the source file that logs the messages or NULL
163 * @param line the line in the source file that logs the message
164 * @param func the name of the function in the source file that logs (or NULL)
165 * @param fmt the format of the message as in printf
166 * @param ... the arguments to the format string of the message
171 __attribute__((format(printf, 6, 7)))
173 void afb_api_x3_verbose(
174 struct afb_api_x3 *api,
184 api->itf->vverbose(api, level, file, line, func, fmt, args);
189 * Retrieves the common systemd's event loop of AFB
191 * @param api the api that uses the event loop
193 * @return the systemd event loop if active, NULL otherwise
195 * @see afb_api_x3_get_user_bus
196 * @see afb_api_x3_get_system_bus
199 struct sd_event *afb_api_x3_get_event_loop(
200 struct afb_api_x3 *api)
202 return api->itf->get_event_loop(api);
206 * Retrieves the common systemd's user/session d-bus of AFB
208 * @param api the api that uses the user dbus
210 * @return the systemd user connection to dbus if active, NULL otherwise
212 * @see afb_api_x3_get_event_loop
213 * @see afb_api_x3_get_system_bus
216 struct sd_bus *afb_api_x3_get_user_bus(
217 struct afb_api_x3 *api)
219 return api->itf->get_user_bus(api);
223 * Retrieves the common systemd's system d-bus of AFB
225 * @param api the api that uses the system dbus
227 * @return the systemd system connection to dbus if active, NULL otherwise
229 * @see afb_api_x3_get_event_loop
230 * @see afb_api_x3_get_user_bus
234 struct sd_bus *afb_api_x3_get_system_bus(
235 struct afb_api_x3 *api)
237 return api->itf->get_system_bus(api);
241 * Get the root directory file descriptor. This file descriptor can
242 * be used with functions 'openat', 'fstatat', ...
244 * CAUTION, manipulate this this descriptor with care, in particular, don't close
247 * This can be used to get the path of the root directory using:
250 * char buffer[MAX_PATH], proc[100];
251 * int dirfd = afb_api_rootdir_get_fd(api);
252 * snprintf(proc, sizeof proc, "/proc/self/fd/%d", dirfd);
253 * readlink(proc, buffer, sizeof buffer);
256 * But note that within AGL this is the value given by the environment variable
257 * AFM_APP_INSTALL_DIR.
259 * @param api the api that uses the directory file descriptor
261 * @return the file descriptor of the root directory.
263 * @see afb_api_x3_rootdir_open_locale
266 int afb_api_x3_rootdir_get_fd(
267 struct afb_api_x3 *api)
269 return api->itf->rootdir_get_fd(api);
273 * Opens 'filename' within the root directory with 'flags' (see function openat)
274 * using the 'locale' definition (example: "jp,en-US") that can be NULL.
276 * The filename must be relative to the root of the bindings.
278 * The opening mode must be for read or write but not for O_CREAT.
280 * The definition of locales and of how files are searched can be checked
281 * here: https://www.w3.org/TR/widgets/#folder-based-localization
282 * and https://tools.ietf.org/html/rfc7231#section-5.3.5
284 * @param api the api that queries the file
285 * @param filename the relative path to the file to open
286 * @param flags the flags for opening as for C function 'open'
287 * @param locale string indicating how to search content, can be NULL
289 * @return the file descriptor or -1 in case of error and errno is set with the
293 * @see afb_api_x3_rootdir_get_fd
296 int afb_api_x3_rootdir_open_locale(
297 struct afb_api_x3 *api,
298 const char *filename,
302 return api->itf->rootdir_open_locale(api, filename, flags, locale);
306 * Queue the job defined by 'callback' and 'argument' for being executed asynchronously
307 * in this thread (later) or in an other thread.
309 * If 'group' is not NULL, the jobs queued with a same value (as the pointer value 'group')
310 * are executed in sequence in the order of there submission.
312 * If 'timeout' is not 0, it represent the maximum execution time for the job in seconds.
313 * At first, the job is called with 0 as signum and the given argument.
315 * The job is executed with the monitoring of its time and some signals like SIGSEGV and
316 * SIGFPE. When a such signal is catched, the job is terminated and reexecuted but with
317 * signum being the signal number (SIGALRM when timeout expired).
319 * When executed, the callback function receives 2 arguments:
321 * - int signum: the signal catched if any or zero at the beginning
322 * - void *arg: the parameter 'argument'
324 * A typical implementation of the job callback is:
327 * void my_job_cb(int signum, void *arg)
329 * struct myarg_t *myarg = arg;
331 * AFB_API_ERROR(myarg->api, "job interrupted with signal %s", strsignal(signum));
333 * really_do_my_job(myarg);
337 * @param api the api that queue the job
338 * @param callback the job as a callback function
339 * @param argument the argument to pass to the queued job
340 * @param group the group of the job, NULL if no group
341 * @param timeout the timeout of execution of the job
343 * @return 0 in case of success or -1 in case of error with errno set appropriately.
346 int afb_api_x3_queue_job(
347 struct afb_api_x3 *api,
348 void (*callback)(int signum, void *arg),
353 return api->itf->queue_job(api, callback, argument, group, timeout);
357 * Check that it requires the API of 'name'.
358 * If 'initialized' is not zero it request the API to be
359 * initialized, implying its initialization if needed.
361 * Calling this function is only allowed within init.
363 * A single request allows to require multiple apis.
365 * @param api the api that requires the other api by its name
366 * @param name a space separated list of required api names
367 * @param initialized if zero, the api is just required to exist. If not zero,
368 * the api is required to exist and to be initialized at return of the call
369 * (initializing it if needed and possible as a side effect of the call).
371 * @return 0 in case of success or -1 in case of error with errno set appropriately.
374 int afb_api_x3_require_api(
375 struct afb_api_x3 *api,
379 return api->itf->require_api(api, name, initialized);
383 * Create an aliased name 'as_name' for the api 'name'.
384 * Calling this function is only allowed within preinit.
386 * @param api the api that requires the aliasing
387 * @param name the api to alias
388 * @param as_name the aliased name of the aliased api
390 * @return 0 in case of success or -1 in case of error with errno set appropriately.
393 int afb_api_x3_add_alias(
394 struct afb_api_x3 *api,
398 return api->itf->add_alias(api, name, as_name);
402 * Broadcasts widely the event of 'name' with the data 'object'.
403 * 'object' can be NULL.
405 * For convenience, the function calls 'json_object_put' for 'object'.
406 * Thus, in the case where 'object' should remain available after
407 * the function returns, the function 'json_object_get' shall be used.
409 * Calling this function is only forbidden during preinit.
411 * The event sent as the name API/name where API is the name of the
414 * @param api the api that broadcast the event
415 * @param name the event name suffix
416 * @param object the object that comes with the event
418 * @return the count of clients that received the event.
421 int afb_api_x3_broadcast_event(
422 struct afb_api_x3 *api,
424 struct json_object *object)
426 return api->itf->event_broadcast(api, name, object);
430 * Creates an event of 'name' and returns it.
432 * Calling this function is only forbidden during preinit.
434 * See afb_event_is_valid to check if there is an error.
436 * The event created as the name API/name where API is the name of the
439 * @param api the api that creates the event
440 * @param name the event name suffix
442 * @return the created event. Use the function afb_event_is_valid to check
443 * whether the event is valid (created) or not (error as reported by errno).
445 * @see afb_event_is_valid
448 struct afb_event_x2 *afb_api_x3_make_event_x2(
449 struct afb_api_x3 *api,
452 return api->itf->event_make(api, name);
456 * @deprecated try to use @ref afb_api_x3_call instead
458 * * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
459 * The result of the call is delivered to the 'callback' function with the 'callback_closure'.
461 * For convenience, the function calls 'json_object_put' for 'args'.
462 * Thus, in the case where 'args' should remain available after
463 * the function returns, the function 'json_object_get' shall be used.
465 * The 'callback' receives 3 arguments:
466 * 1. 'closure' the user defined closure pointer 'closure',
467 * 2. 'status' a status being 0 on success or negative when an error occurred,
468 * 2. 'result' the resulting data as a JSON object.
471 * @param apiname The api name of the method to call
472 * @param verb The verb name of the method to call
473 * @param args The arguments to pass to the method
474 * @param callback The to call on completion
475 * @param closure The closure to pass to the callback
477 * @see also 'afb_api_call'
478 * @see also 'afb_api_call_sync'
479 * @see also 'afb_api_call_sync_legacy'
480 * @see also 'afb_req_subcall'
481 * @see also 'afb_req_subcall_sync'
484 void afb_api_x3_call_legacy(
485 struct afb_api_x3 *api,
488 struct json_object *args,
489 void (*callback)(void *closure,
491 struct json_object *result,
492 struct afb_api_x3 *api),
495 api->itf->legacy_call(api, apiname, verb, args, callback, closure);
499 * @deprecated try to use @ref afb_api_x3_call_sync instead
501 * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
502 * 'result' will receive the response.
504 * For convenience, the function calls 'json_object_put' for 'args'.
505 * Thus, in the case where 'args' should remain available after
506 * the function returns, the function 'json_object_get' shall be used.
509 * @param apiname The api name of the method to call
510 * @param verb The verb name of the method to call
511 * @param args The arguments to pass to the method
512 * @param result Where to store the result - should call json_object_put on it -
514 * @returns 0 in case of success or a negative value in case of error.
516 * @see also 'afb_api_call'
517 * @see also 'afb_api_call_sync'
518 * @see also 'afb_api_call_legacy'
519 * @see also 'afb_req_subcall'
520 * @see also 'afb_req_subcall_sync'
523 int afb_api_x3_call_sync_legacy(
524 struct afb_api_x3 *api,
527 struct json_object *args,
528 struct json_object **result)
530 return api->itf->legacy_call_sync(api, apiname, verb, args, result);
534 * Creates a new api of name 'apiname' briefly described by 'info' (that can
537 * When the pre-initialization function is given, it is a function that
538 * receives 2 parameters:
540 * - the closure as given in the call
541 * - the created api that can be initialised
543 * This pre-initialization function must return a negative value to abort
544 * the creation of the api. Otherwise, it returns a non-negative value to
547 * @param api the api that creates the other one
548 * @param apiname the name of the new api
549 * @param info the brief description of the new api (can be NULL)
550 * @param noconcurrency zero or not zero whether the new api is reentrant or not
551 * @param preinit the pre-initialization function if any (can be NULL)
552 * @param closure the closure for the pre-initialization preinit
554 * @return the created api in case of success or NULL on error
556 * @see afb_api_x3_delete_api
559 struct afb_api_x3 *afb_api_x3_new_api(
560 struct afb_api_x3 *api,
564 int (*preinit)(void*, struct afb_api_x3 *),
567 return api->itf->api_new_api(api, apiname, info, noconcurrency, preinit, closure);
571 * @deprecated use @ref afb_api_x3_set_verbs_v3 instead
573 * Set the verbs of the 'api' using description of verbs of the api v2
575 * @param api the api that will get the verbs
576 * @param verbs the array of verbs to add terminated with an item with name=NULL
578 * @return 0 in case of success or -1 on failure with errno set
581 * @see afb_api_x3_add_verb
582 * @see afb_api_x3_set_verbs_v3
585 int afb_api_x3_set_verbs_v2(
586 struct afb_api_x3 *api,
587 const struct afb_verb_v2 *verbs)
589 return api->itf->api_set_verbs_v2(api, verbs);
593 * Add one verb to the dynamic set of the api
595 * @param api the api to change
596 * @param verb name of the verb
597 * @param info brief description of the verb, can be NULL
598 * @param callback callback function implementing the verb
599 * @param vcbdata data for the verb callback, available through req
600 * @param auth required authorization, can be NULL
601 * @param session authorization and session requirements of the verb
602 * @param glob is the verb glob name
604 * @return 0 in case of success or -1 on failure with errno set
607 * @see afb_api_x3_del_verb
608 * @see afb_api_x3_set_verbs_v3
609 * @see fnmatch for matching names using glob
612 int afb_api_x3_add_verb(
613 struct afb_api_x3 *api,
616 void (*callback)(struct afb_req_x2 *req),
618 const struct afb_auth *auth,
622 return api->itf->api_add_verb(api, verb, info, callback, vcbdata, auth, session, glob);
626 * Delete one verb from the dynamic set of the api
628 * @param api the api to change
629 * @param verb name of the verb to delete
630 * @param vcbdata if not NULL will receive the vcbdata of the deleted verb
632 * @return 0 in case of success or -1 on failure with errno set
634 * @see afb_api_x3_add_verb
637 int afb_api_x3_del_verb(
638 struct afb_api_x3 *api,
642 return api->itf->api_del_verb(api, verb, vcbdata);
646 * Set the callback 'onevent' to process events in the name of the 'api'.
648 * This setting can be done statically using the global variable
651 * This function replace any previously global event callback set.
653 * When an event is received, the callback 'onevent' is called with 3 parameters
655 * - the api that recorded the event handler
656 * - the full name of the event
657 * - the companion JSON object of the event
659 * @param api the api that wants to process events
660 * @param onevent the callback function that will process events (can be NULL
661 * to remove event callback)
663 * @return 0 in case of success or -1 on failure with errno set
666 * @see afb_binding_v3
667 * @see afb_api_x3_event_handler_add
668 * @see afb_api_x3_event_handler_del
671 int afb_api_x3_on_event(
672 struct afb_api_x3 *api,
674 struct afb_api_x3 *api,
676 struct json_object *object))
678 return api->itf->api_set_on_event(api, onevent);
682 * Set the callback 'oninit' to process initialization of the 'api'.
684 * This setting can be done statically using the global variable
687 * This function replace any previously initialization callback set.
689 * This function is only valid during the pre-initialization stage.
691 * The callback initialization function will receive one argument: the api
694 * @param api the api that wants to process events
695 * @param oninit the callback function that initialize the api
697 * @return 0 in case of success or -1 on failure with errno set
700 * @see afb_binding_v3
703 int afb_api_x3_on_init(
704 struct afb_api_x3 *api,
705 int (*oninit)(struct afb_api_x3 *api))
707 return api->itf->api_set_on_init(api, oninit);
711 * Seal the api. After a call to this function the api can not be modified
714 * @param api the api to be sealed
717 void afb_api_x3_seal(
718 struct afb_api_x3 *api)
720 api->itf->api_seal(api);
724 * Set the verbs of the 'api' using description of verbs of the api v2
726 * @param api the api that will get the verbs
727 * @param verbs the array of verbs to add terminated with an item with name=NULL
729 * @return 0 in case of success or -1 on failure with errno set
732 * @see afb_api_x3_add_verb
733 * @see afb_api_x3_del_verb
736 int afb_api_x3_set_verbs_v3(
737 struct afb_api_x3 *api,
738 const struct afb_verb_v3 *verbs)
740 return api->itf->api_set_verbs_v3(api, verbs);
744 * Add a specific event handler for the api
746 * The handler callback is called when an event matching the given pattern
747 * is received (it is received if broadcasted or after subscription through
748 * a call or a subcall).
750 * The handler callback receive 4 arguments:
752 * - the closure given here
753 * - the event full name
754 * - the companion JSON object of the event
755 * - the api that subscribed the event
757 * @param api the api that creates the handler
758 * @param pattern the global pattern of the event to handle
759 * @param callback the handler callback function
760 * @param closure the closure of the handler
762 * @return 0 in case of success or -1 on failure with errno set
764 * @see afb_api_x3_on_event
765 * @see afb_api_x3_event_handler_del
768 int afb_api_x3_event_handler_add(
769 struct afb_api_x3 *api,
778 return api->itf->event_handler_add(api, pattern, callback, closure);
782 * Delete a specific event handler for the api
784 * @param api the api that the handler belongs to
785 * @param pattern the global pattern of the handler to remove
786 * @param closure if not NULL it will receive the closure set to the handler
788 * @return 0 in case of success or -1 on failure with errno set
790 * @see afb_api_x3_on_event
791 * @see afb_api_x3_event_handler_add
794 int afb_api_x3_event_handler_del(
795 struct afb_api_x3 *api,
799 return api->itf->event_handler_del(api, pattern, closure);
803 * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
804 * The result of the call is delivered to the 'callback' function with the 'callback_closure'.
806 * For convenience, the function calls 'json_object_put' for 'args'.
807 * Thus, in the case where 'args' should remain available after
808 * the function returns, the function 'json_object_get' shall be used.
810 * The 'callback' receives 5 arguments:
811 * 1. 'closure' the user defined closure pointer 'closure',
812 * 2. 'object' a JSON object returned (can be NULL)
813 * 3. 'error' a string not NULL in case of error but NULL on success
814 * 4. 'info' a string handling some info (can be NULL)
817 * @param api The api that makes the call
818 * @param apiname The api name of the method to call
819 * @param verb The verb name of the method to call
820 * @param args The arguments to pass to the method
821 * @param callback The to call on completion
822 * @param closure The closure to pass to the callback
825 * @see afb_req_subcall
826 * @see afb_req_subcall_sync
827 * @see afb_api_x3_call_sync
830 void afb_api_x3_call(
831 struct afb_api_x3 *api,
834 struct json_object *args,
837 struct json_object *object,
840 struct afb_api_x3 *api),
843 api->itf->call(api, apiname, verb, args, callback, closure);
847 * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
848 * 'result' will receive the response.
850 * For convenience, the function calls 'json_object_put' for 'args'.
851 * Thus, in the case where 'args' should remain available after
852 * the function returns, the function 'json_object_get' shall be used.
854 * @param api The api that makes the call
855 * @param apiname The api name of the method to call
856 * @param verb The verb name of the method to call
857 * @param args The arguments to pass to the method
858 * @param object Where to store the returned object - should call json_object_put on it - can be NULL
859 * @param error Where to store the copied returned error - should call free on it - can be NULL
860 * @param info Where to store the copied returned info - should call free on it - can be NULL
862 * @returns 0 in case of success or a negative value in case of error.
864 * @see afb_req_subcall
865 * @see afb_req_subcall_sync
866 * @see afb_api_x3_call
869 int afb_api_x3_call_sync(
870 struct afb_api_x3 *api,
873 struct json_object *args,
874 struct json_object **object,
878 return api->itf->call_sync(api, apiname, verb, args, object, error, info);
882 * Tells that the api provides a class of features. Classes are intended to
883 * allow ordering of initializations: apis that provides a given class are
884 * initialized before apis requiring it.
886 * This function is only valid during the pre-initialization stage.
888 * @param api the api that provides the classes
889 * @param name a space separated list of the names of the provided classes
891 * @returns 0 in case of success or a negative value in case of error.
893 * @see afb_api_x3_require_class
896 int afb_api_x3_provide_class(
897 struct afb_api_x3 *api,
900 return api->itf->class_provide(api, name);
904 * Tells that the api requires a set of class features. Classes are intended to
905 * allow ordering of initializations: apis that provides a given class are
906 * initialized before apis requiring it.
908 * This function is only valid during the pre-initialization stage.
910 * @param api the api that requires the classes
911 * @param name a space separated list of the names of the required classes
913 * @returns 0 in case of success or a negative value in case of error.
915 * @see afb_api_x3_provide_class
918 int afb_api_x3_require_class(
919 struct afb_api_x3 *api,
922 return api->itf->class_require(api, name);
926 * Delete the given api.
928 * It is of the responsibility of the caller to don't used the deleted api
929 * anymore after this function returned.
931 * @param api the api to delete
933 * @returns 0 in case of success or a negative value in case of error.
935 * @see afb_api_x3_new_api
938 int afb_api_x3_delete_api(
939 struct afb_api_x3 *api)
941 return api->itf->delete_api(api);
945 * Settings of the api.
947 * Get the settings of the API. The settings are recorded
948 * as a JSON object. The returned object should not be modified.
949 * It MUST NOT be released using json_object_put.
951 * @param api the api whose settings are required
953 * @returns The setting object.
956 struct json_object *afb_api_x3_settings(
957 struct afb_api_x3 *api)
959 return api->itf->settings(api);