api-v3: First draft
[src/app-framework-binder.git] / include / afb / afb-req-x2.h
1 /*
2  * Copyright (C) 2016, 2017, 2018 "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-req-x2-itf.h"
21 #include "afb-api-x3.h"
22
23 /**
24  * Checks whether the request 'req' is valid or not.
25  *
26  * @param req the request to check
27  *
28  * @return 0 if not valid or 1 if valid.
29  */
30 static inline
31 int afb_req_x2_is_valid(
32                         struct afb_req_x2 *req)
33 {
34         return !!req;
35 }
36
37 /**
38  * Retrieves the api that serves the request
39  *
40  * @param req the request whose serving api is queried
41  *
42  * @return the api serving the request
43  */
44 static inline
45 struct afb_api_x3 *afb_req_x2_get_api(
46                         struct afb_req_x2 *req)
47 {
48         return req->api;
49 }
50
51 /**
52  * Retrieves the callback data of the verb. This callback data is set
53  * when the verb is created.
54  *
55  * @param req whose verb vcbdata is queried
56  *
57  * @return the callback data attached to the verb description
58  */
59 static inline
60 void *afb_req_x2_get_vcbdata(
61                         struct afb_req_x2 *req)
62 {
63         return req->vcbdata;
64 }
65
66 /**
67  * Retrieve the name of the called api.
68  *
69  * @param req the request
70  *
71  * @return the name of the called api
72  *
73  * @see afb_api_x3_add_alias
74  */
75 static inline
76 const char *afb_req_x2_get_called_api(
77                         struct afb_req_x2 *req)
78 {
79         return req->called_api;
80 }
81
82 /**
83  * Retrieve the name of the called verb
84  *
85  * @param req the request
86  *
87  * @return the name of the called verb
88  */
89 static inline
90 const char *afb_req_x2_get_called_verb(
91                         struct afb_req_x2 *req)
92 {
93         return req->called_verb;
94 }
95
96 /**
97  * Is the log message of 'level (as defined for syslog) required for the
98  * request 'req'?
99  *
100  * @param req the request
101  * @param level the level to check as defined for syslog:
102  *
103  *      EMERGENCY         0        System is unusable
104  *      ALERT             1        Action must be taken immediately
105  *      CRITICAL          2        Critical conditions
106  *      ERROR             3        Error conditions
107  *      WARNING           4        Warning conditions
108  *      NOTICE            5        Normal but significant condition
109  *      INFO              6        Informational
110  *      DEBUG             7        Debug-level messages
111  *
112  * @return 0 if not required or a value not null if required
113  *
114  * @see syslog
115  */
116 static inline
117 int afb_req_x2_wants_log_level(
118                         struct afb_req_x2 *req,
119                         int level)
120 {
121         return afb_api_x3_wants_log_level(afb_req_x2_get_api(req), level);
122 }
123
124 /**
125  * Gets from the request 'req' the argument of 'name'.
126  *
127  * Returns a PLAIN structure of type 'struct afb_arg'.
128  *
129  * When the argument of 'name' is not found, all fields of result are set to NULL.
130  *
131  * When the argument of 'name' is found, the fields are filled,
132  * in particular, the field 'result.name' is set to 'name'.
133  *
134  * There is a special name value: the empty string.
135  * The argument of name "" is defined only if the request was made using
136  * an HTTP POST of Content-Type "application/json". In that case, the
137  * argument of name "" receives the value of the body of the HTTP request.
138  *
139  * @param req the request
140  * @param name the name of the argument to get
141  *
142  * @return a structure describing the retrieved argument for the request
143  *
144  * @see afb_req_x2_value
145  * @see afb_req_x2_path
146  */
147 static inline
148 struct afb_arg afb_req_x2_get(
149                         struct afb_req_x2 *req,
150                         const char *name)
151 {
152         return req->itf->get(req, name);
153 }
154
155 /**
156  * Gets from the request 'req' the string value of the argument of 'name'.
157  * Returns NULL if when there is no argument of 'name'.
158  * Returns the value of the argument of 'name' otherwise.
159  *
160  * Shortcut for: afb_req_x2_get(req, name).value
161  *
162  * @param req the request
163  * @param name the name of the argument's value to get
164  *
165  * @return the value as a string or NULL
166  *
167  * @see afb_req_x2_get
168  * @see afb_req_x2_path
169  */
170 static inline
171 const char *afb_req_x2_value(
172                         struct afb_req_x2 *req,
173                         const char *name)
174 {
175         return afb_req_x2_get(req, name).value;
176 }
177
178 /**
179  * Gets from the request 'req' the path for file attached to the argument of 'name'.
180  * Returns NULL if when there is no argument of 'name' or when there is no file.
181  * Returns the path of the argument of 'name' otherwise.
182  *
183  * Shortcut for: afb_req_x2_get(req, name).path
184  *
185  * @param req the request
186  * @param name the name of the argument's path to get
187  *
188  * @return the path if any or NULL
189  *
190  * @see afb_req_x2_get
191  * @see afb_req_x2_value
192  */
193 static inline
194 const char *afb_req_x2_path(
195                         struct afb_req_x2 *req,
196                         const char *name)
197 {
198         return afb_req_x2_get(req, name).path;
199 }
200
201 /**
202  * Gets from the request 'req' the json object hashing the arguments.
203  *
204  * The returned object must not be released using 'json_object_put'.
205  *
206  * @param req the request
207  *
208  * @return the JSON object of the query
209  *
210  * @see afb_req_x2_get
211  * @see afb_req_x2_value
212  * @see afb_req_x2_path
213  */
214 static inline
215 struct json_object *afb_req_x2_json(
216                         struct afb_req_x2 *req)
217 {
218         return req->itf->json(req);
219 }
220
221 /**
222  * Sends a reply to the request 'req'.
223  *
224  * The status of the reply is set to 'error' (that must be NULL on success).
225  * Its send the object 'obj' (can be NULL) with an
226  * informational comment 'info (can also be NULL).
227  *
228  * For convenience, the function calls 'json_object_put' for 'obj'.
229  * Thus, in the case where 'obj' should remain available after
230  * the function returns, the function 'json_object_get' shall be used.
231  *
232  * @param req the request
233  * @param obj the replied object or NULL
234  * @param error the error message if it is a reply error or NULL
235  * @param info an informative text or NULL
236  *
237  * @see afb_req_x2_reply_v
238  * @see afb_req_x2_reply_f
239  */
240 static inline
241 void afb_req_x2_reply(
242                         struct afb_req_x2 *req,
243                         struct json_object *obj,
244                         const char *error,
245                         const char *info)
246 {
247         req->itf->reply(req, obj, error, info);
248 }
249
250 /**
251  * Same as 'afb_req_x2_reply_f' but the arguments to the format 'info'
252  * are given as a variable argument list instance.
253  *
254  * For convenience, the function calls 'json_object_put' for 'obj'.
255  * Thus, in the case where 'obj' should remain available after
256  * the function returns, the function 'json_object_get' shall be used.
257  *
258  * @param req the request
259  * @param obj the replied object or NULL
260  * @param error the error message if it is a reply error or NULL
261  * @param info an informative text containing a format as for vprintf
262  * @param args the va_list of arguments to the format as for vprintf
263  *
264  * @see afb_req_x2_reply
265  * @see afb_req_x2_reply_f
266  * @see vprintf
267  */
268 static inline
269 void afb_req_x2_reply_v(
270                         struct afb_req_x2 *req,
271                         struct json_object *obj,
272                         const char *error,
273                         const char *info,
274                         va_list args)
275 {
276         req->itf->vreply(req, obj, error, info, args);
277 }
278
279 /**
280  * Same as 'afb_req_x2_reply' but the 'info' is a formatting
281  * string followed by arguments.
282  *
283  * For convenience, the function calls 'json_object_put' for 'obj'.
284  * Thus, in the case where 'obj' should remain available after
285  * the function returns, the function 'json_object_get' shall be used.
286  *
287  * @param req the request
288  * @param obj the replied object or NULL
289  * @param error the error message if it is a reply error or NULL
290  * @param info an informative text containing a format as for printf
291  * @param ... the arguments to the format as for printf
292  *
293  * @see afb_req_x2_reply
294  * @see afb_req_x2_reply_v
295  * @see printf
296  */
297 __attribute__((format(printf, 4, 5)))
298 static inline
299 void afb_req_x2_reply_f(
300                         struct afb_req_x2 *req,
301                         struct json_object *obj,
302                         const char *error,
303                         const char *info,
304                         ...)
305 {
306         va_list args;
307         va_start(args, info);
308         afb_req_x2_reply_v(req, obj, error, info, args);
309         va_end(args);
310 }
311
312 /**
313  * Manage the pointer stored by the binding for the client session of 'req'.
314  *
315  * If no previous pointer is stored or if 'replace' is not zero, a new value
316  * is generated using the function 'create_context' called with the 'closure'.
317  * If 'create_context' is NULL the generated value is 'closure'.
318  *
319  * When a value is created, the function 'free_context' is recorded and will
320  * be called (with the created value as argument) to free the created value when
321  * it is not more used.
322  *
323  * This function is atomic: it ensures that 2 threads will not race together.
324  *
325  * @param req the request
326  * @param replace if not zero an existing value is replaced
327  * @param create_context the creation function or NULL
328  * @param free_context the destroying function or NULL
329  * @param closure the closure to the creation function
330  *
331  * @return the stored value
332  */
333 static inline
334 void *afb_req_x2_context(
335                         struct afb_req_x2 *req,
336                         int replace,
337                         void *(*create_context)(void *closure),
338                         void (*free_context)(void*),
339                         void *closure)
340 {
341         return req->itf->context_make(req, replace, create_context, free_context, closure);
342 }
343
344 /**
345  * Gets the pointer stored by the binding for the session of 'req'.
346  * When the binding has not yet recorded a pointer, NULL is returned.
347  *
348  * Shortcut for: afb_req_x2_context(req, 0, NULL, NULL, NULL)
349  *
350  * @param req the request
351  *
352  * @return the previously stored value
353  */
354 static inline
355 void *afb_req_x2_context_get(
356                         struct afb_req_x2 *req)
357 {
358         return afb_req_x2_context(req, 0, 0, 0, 0);
359 }
360
361 /**
362  * Stores for the binding the pointer 'context' to the session of 'req'.
363  * The function 'free_context' will be called when the session is closed
364  * or if binding stores an other pointer.
365  *
366  * Shortcut for: afb_req_x2_context(req, 1, NULL, free_context, context)
367  *
368  *
369  * @param req the request
370  * @param context the context value to store
371  * @param free_context the cleaning function for the stored context (can be NULL)
372  */
373 static inline
374 void afb_req_x2_context_set(
375                         struct afb_req_x2 *req,
376                         void *context,
377                         void (*free_context)(void*))
378 {
379         afb_req_x2_context(req, 1, 0, free_context, context);
380 }
381
382 /**
383  * Frees the pointer stored by the binding for the session of 'req'
384  * and sets it to NULL.
385  *
386  * Shortcut for: afb_req_x2_context_set(req, NULL, NULL)
387  *
388  * @param req the request
389  */
390 static inline
391 void afb_req_x2_context_clear(
392                         struct afb_req_x2 *req)
393 {
394         afb_req_x2_context(req, 1, 0, 0, 0);
395 }
396
397 /**
398  * Increments the count of references of 'req'.
399  *
400  * @param req the request
401  *
402  * @return returns the request req
403  */
404 static inline
405 struct afb_req_x2 *afb_req_x2_addref(
406                         struct afb_req_x2 *req)
407 {
408         return req->itf->addref(req);
409 }
410
411 /**
412  * Decrement the count of references of 'req'.
413  *
414  * @param req the request
415  */
416 static inline
417 void afb_req_x2_unref(
418                         struct afb_req_x2 *req)
419 {
420         req->itf->unref(req);
421 }
422
423 /**
424  * Closes the session associated with 'req'
425  * and delete all associated contexts.
426  *
427  * @param req the request
428  */
429 static inline
430 void afb_req_x2_session_close(
431                         struct afb_req_x2 *req)
432 {
433         req->itf->session_close(req);
434 }
435
436 /**
437  * Sets the level of assurance of the session of 'req'
438  * to 'level'. The effect of this function is subject of
439  * security policies.
440  *
441  * @param req the request
442  * @param level of assurance from 0 to 7
443  *
444  * @return 0 on success or -1 if failed.
445  */
446 static inline
447 int afb_req_x2_session_set_LOA(
448                         struct afb_req_x2 *req,
449                         unsigned level)
450 {
451         return req->itf->session_set_LOA(req, level);
452 }
453
454 /**
455  * Establishes for the client link identified by 'req' a subscription
456  * to the 'event'.
457  *
458  * @param req the request
459  * @param event the event to subscribe
460  *
461  * @return 0 in case of successful subscription or -1 in case of error.
462  */
463 static inline
464 int afb_req_x2_subscribe(
465                         struct afb_req_x2 *req,
466                         struct afb_event_x2 *event)
467 {
468         return req->itf->subscribe_event_x2(req, event);
469 }
470
471 /**
472  * Revokes the subscription established to the 'event' for the client
473  * link identified by 'req'.
474  * Returns 0 in case of successful subscription or -1 in case of error.
475  *
476  * @param req the request
477  * @param event the event to revoke
478  *
479  * @return 0 in case of successful subscription or -1 in case of error.
480  */
481 static inline
482 int afb_req_x2_unsubscribe(
483                         struct afb_req_x2 *req,
484                         struct afb_event_x2 *event)
485 {
486         return req->itf->unsubscribe_event_x2(req, event);
487 }
488
489 /**
490  * @deprecated use @ref afb_req_x2_subcall
491  *
492  * Makes a call to the method of name 'api' / 'verb' with the object 'args'.
493  * This call is made in the context of the request 'req'.
494  * On completion, the function 'callback' is invoked with the
495  * 'closure' given at call and two other parameters: 'iserror' and 'result'.
496  * 'status' is 0 on success or negative when on an error reply.
497  * 'result' is the json object of the reply, you must not call json_object_put
498  * on the result.
499  *
500  * For convenience, the function calls 'json_object_put' for 'args'.
501  * Thus, in the case where 'args' should remain available after
502  * the function returns, the function 'json_object_get' shall be used.
503  *
504  * @param req the request
505  * @param api the name of the api to call
506  * @param verb the name of the verb to call
507  * @param args the arguments of the call as a JSON object
508  * @param callback the call back that will receive the reply
509  * @param closure the closure passed back to the callback
510  *
511  * @see afb_req_x2_subcall
512  * @see afb_req_x2_subcall_sync
513  */
514 static inline
515 void afb_req_x2_subcall_legacy(
516                         struct afb_req_x2 *req,
517                         const char *api,
518                         const char *verb,
519                         struct json_object *args,
520                         void (*callback)(void *closure, int iserror, struct json_object *result, struct afb_req_x2 *req),
521                         void *closure)
522 {
523         req->itf->legacy_subcall_request(req, api, verb, args, callback, closure);
524 }
525
526 /**
527  * @deprecated use @ref afb_req_x2_subcall_sync
528  *
529  * Makes a call to the method of name 'api' / 'verb' with the object 'args'.
530  * This call is made in the context of the request 'req'.
531  * This call is synchronous, it waits untill completion of the request.
532  * It returns 0 on success or a negative value on error answer.
533  * The object pointed by 'result' is filled and must be released by the caller
534  * after its use by calling 'json_object_put'.
535  *
536  * For convenience, the function calls 'json_object_put' for 'args'.
537  * Thus, in the case where 'args' should remain available after
538  * the function returns, the function 'json_object_get' shall be used.
539  *
540  * @param req the request
541  * @param api the name of the api to call
542  * @param verb the name of the verb to call
543  * @param args the arguments of the call as a JSON object
544  * @param result the pointer to the JSON object pointer that will receive the result
545  *
546  * @return 0 on success or a negative value on error answer.
547  *
548  * @see afb_req_x2_subcall
549  * @see afb_req_x2_subcall_sync
550  */
551 static inline
552 int afb_req_x2_subcall_sync_legacy(
553                         struct afb_req_x2 *req,
554                         const char *api,
555                         const char *verb,
556                         struct json_object *args,
557                         struct json_object **result)
558 {
559         return req->itf->legacy_subcallsync(req, api, verb, args, result);
560 }
561
562 /**
563  * Send associated to 'req' a message described by 'fmt' and following parameters
564  * to the journal for the verbosity 'level'.
565  *
566  * 'file', 'line' and 'func' are indicators of position of the code in source files
567  * (see macros __FILE__, __LINE__ and __func__).
568  *
569  * 'level' is defined by syslog standard:
570  *      EMERGENCY         0        System is unusable
571  *      ALERT             1        Action must be taken immediately
572  *      CRITICAL          2        Critical conditions
573  *      ERROR             3        Error conditions
574  *      WARNING           4        Warning conditions
575  *      NOTICE            5        Normal but significant condition
576  *      INFO              6        Informational
577  *      DEBUG             7        Debug-level messages
578  *
579  * @param req the request
580  * @param level the level of the message
581  * @param file the source filename that emits the message or NULL
582  * @param line the line number in the source filename that emits the message
583  * @param func the name of the function that emits the message or NULL
584  * @param fmt the message format as for printf
585  * @param ... the arguments of the printf
586  *
587  * @see printf
588  */
589 __attribute__((format(printf, 6, 7)))
590 static inline
591 void afb_req_x2_verbose(
592                         struct afb_req_x2 *req,
593                         int level, const char *file,
594                         int line,
595                         const char * func,
596                         const char *fmt,
597                         ...)
598 {
599         va_list args;
600         va_start(args, fmt);
601         req->itf->vverbose(req, level, file, line, func, fmt, args);
602         va_end(args);
603 }
604
605 /**
606  * Check whether the 'permission' is granted or not to the client
607  * identified by 'req'.
608  *
609  * @param req the request
610  * @param permission string to check
611  *
612  * @return 1 if the permission is granted or 0 otherwise.
613  */
614 static inline
615 int afb_req_x2_has_permission(
616                         struct afb_req_x2 *req,
617                         const char *permission)
618 {
619         return req->itf->has_permission(req, permission);
620 }
621
622 /**
623  * Get the application identifier of the client application for the
624  * request 'req'.
625  *
626  * Returns the application identifier or NULL when the application
627  * can not be identified.
628  *
629  * The returned value if not NULL must be freed by the caller
630  *
631  * @param req the request
632  *
633  * @return the string for the application id of the client MUST BE FREED
634  */
635 static inline
636 char *afb_req_x2_get_application_id(
637                         struct afb_req_x2 *req)
638 {
639         return req->itf->get_application_id(req);
640 }
641
642 /**
643  * Get the user identifier (UID) of the client for the
644  * request 'req'.
645  *
646  * @param req the request
647  *
648  * @return -1 when the application can not be identified or the unix uid.
649  *
650  */
651 static inline
652 int afb_req_x2_get_uid(
653                         struct afb_req_x2 *req)
654 {
655         return req->itf->get_uid(req);
656 }
657
658 /**
659  * Get informations about the client of the
660  * request 'req'.
661  *
662  * Returns an object with client informations:
663  *  {
664  *    "pid": int, "uid": int, "gid": int,
665  *    "label": string, "id": string, "user": string,
666  *    "uuid": string, "LOA": int
667  *  }
668  *
669  * If some of this information can't be computed, the field of the return
670  * object will not be set at all.
671  *
672  * @param req the request
673  *
674  * @return a JSON object that must be freed using @ref json_object_put
675  */
676 static inline
677 struct json_object *afb_req_x2_get_client_info(
678                         struct afb_req_x2 *req)
679 {
680         return req->itf->get_client_info(req);
681 }
682
683 /**
684  * Calls the 'verb' of the 'api' with the arguments 'args' and 'verb' in the name of the binding.
685  * The result of the call is delivered to the 'callback' function with the 'callback_closure'.
686  *
687  * For convenience, the function calls 'json_object_put' for 'args'.
688  * Thus, in the case where 'args' should remain available after
689  * the function returns, the function 'json_object_get' shall be used.
690  *
691  * The 'callback' receives 5 arguments:
692  *  1. 'closure' the user defined closure pointer 'closure',
693  *  2. 'object'  a JSON object returned (can be NULL)
694  *  3. 'error'   a string not NULL in case of error
695  *  4. 'info'    a string handling some info (can be NULL)
696  *  5. 'req'     the req
697  *
698  * @param req      The request
699  * @param api      The api name of the method to call
700  * @param verb     The verb name of the method to call
701  * @param args     The arguments to pass to the method
702  * @param flags    The bit field of flags for the subcall as defined by @ref afb_req_x2_subcall_flags
703  * @param callback The to call on completion
704  * @param closure  The closure to pass to the callback
705  *
706  * @see also 'afb_req_subcall_sync'
707  */
708 static inline
709 void afb_req_x2_subcall(
710                         struct afb_req_x2 *req,
711                         const char *api,
712                         const char *verb,
713                         struct json_object *args,
714                         int flags,
715                         void (*callback)(void *closure, struct json_object *object, const char *error, const char * info, struct afb_req_x2 *req),
716                         void *closure)
717 {
718         req->itf->subcall(req, api, verb, args, flags, callback, closure);
719 }
720
721 /**
722  * Makes a call to the method of name 'api' / 'verb' with the object 'args'.
723  * This call is made in the context of the request 'req'.
724  * This call is synchronous, it waits untill completion of the request.
725  * It returns 0 on success or a negative value on error answer.
726  *
727  * For convenience, the function calls 'json_object_put' for 'args'.
728  * Thus, in the case where 'args' should remain available after
729  * the function returns, the function 'json_object_get' shall be used.
730  *
731  * See also:
732  *  - 'afb_req_x2_subcall_req' that is convenient to keep request alive automatically.
733  *  - 'afb_req_x2_subcall' that doesn't keep request alive automatically.
734  *
735  * @param req      The request
736  * @param api      The api name of the method to call
737  * @param verb     The verb name of the method to call
738  * @param args     The arguments to pass to the method
739  * @param flags    The bit field of flags for the subcall as defined by @ref afb_req_x2_subcall_flags
740  * @param object   a pointer where the replied JSON object is stored must be freed using @ref json_object_put (can be NULL)
741  * @param error    a pointer where a copy of the replied error is stored must be freed using @ref free (can be NULL)
742  * @param info     a pointer where a copy of the replied info is stored must be freed using @ref free (can be NULL)
743  *
744  * @return 0 in case of success or -1 in case of error
745  */
746 static inline
747 int afb_req_x2_subcall_sync(
748                         struct afb_req_x2 *req,
749                         const char *api,
750                         const char *verb,
751                         struct json_object *args,
752                         int flags,
753                         struct json_object **object,
754                         char **error,
755                         char **info)
756 {
757         return req->itf->subcallsync(req, api, verb, args, flags, object, error, info);
758 }