6e062b2ec20a92426aa8db50d5c368883ca225d0
[src/app-framework-binder.git] / include / afb / afb-binding.hpp
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 <cstdlib>
21 #include <cstdarg>
22 #include <functional>
23
24 /* ensure version */
25 #ifndef AFB_BINDING_VERSION
26 # define AFB_BINDING_VERSION   2
27 #endif
28
29 /* check the version */
30 #if AFB_BINDING_VERSION < 2
31 # error "AFB_BINDING_VERSION must be at least 2"
32 #endif
33
34 /* get C definitions of bindings */
35 extern "C" {
36 #include "afb-binding.h"
37 }
38
39 namespace afb {
40 /*************************************************************************/
41 /* pre-declaration of classes                                            */
42 /*************************************************************************/
43
44 class arg;
45 class event;
46 class req;
47 class stored_req;
48
49 /*************************************************************************/
50 /* declaration of functions                                              */
51 /*************************************************************************/
52
53 struct sd_event *get_event_loop();
54 struct sd_bus *get_system_bus();
55 struct sd_bus *get_user_bus();
56
57 int broadcast_event(const char *name, json_object *object = nullptr);
58
59 event make_event(const char *name);
60
61 void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args);
62
63 void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...);
64
65 int rootdir_get_fd();
66
67 int rootdir_open_locale_fd(const char *filename, int flags, const char *locale = nullptr);
68
69 int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout);
70
71 int require_api(const char *apiname, bool initialized = true);
72
73 int rename_api(const char *apiname);
74
75 int verbosity();
76
77 bool wants_errors();
78 bool wants_warnings();
79 bool wants_notices();
80 bool wants_infos();
81 bool wants_debugs();
82
83 void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result), void *closure);
84
85 template <class T> void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, int iserror, struct json_object *result), T *closure);
86
87 bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result);
88
89 /*************************************************************************/
90 /* effective declaration of classes                                      */
91 /*************************************************************************/
92
93 /* events */
94 class event
95 {
96         struct afb_event event_;
97 public:
98         event() { event_.itf = nullptr; event_.closure = nullptr; }
99         event(const struct afb_event &e);
100         event(const event &other);
101         event &operator=(const event &other);
102
103         operator const struct afb_event&() const;
104
105         operator bool() const;
106         bool is_valid() const;
107
108         void invalidate();
109
110         int broadcast(json_object *object) const;
111         int push(json_object *object) const;
112
113         void unref();
114         void addref();
115         const char *name() const;
116 };
117
118 /* args */
119 class arg
120 {
121         struct afb_arg arg_;
122 public:
123         arg() = delete;
124         arg(const struct afb_arg &a);
125         arg(const arg &other);
126         arg &operator=(const arg &other);
127
128         operator const struct afb_arg&() const;
129
130         bool has_name() const;
131         bool has_value() const;
132         bool has_path() const;
133
134         const char *name() const;
135         const char *value() const;
136         const char *path() const;
137 };
138
139 /* req(uest) */
140 class req
141 {
142         struct afb_req req_;
143 public:
144         class stored
145         {
146                 struct afb_stored_req *sreq_;
147
148                 friend class req;
149                 stored() = delete;
150                 stored(struct afb_stored_req *sr);
151         public:
152                 stored(const stored &other);
153                 stored &operator =(const stored &other);
154                 req unstore() const;
155         };
156
157         class stored;
158
159 public:
160         req() = delete;
161         req(const struct afb_req &r);
162         req(const req &other);
163         req &operator=(const req &other);
164
165         operator const struct afb_req&() const;
166
167         operator bool() const;
168         bool is_valid() const;
169
170         arg get(const char *name) const;
171
172         const char *value(const char *name) const;
173
174         const char *path(const char *name) const;
175
176         json_object *json() const;
177
178         void success(json_object *obj = nullptr, const char *info = nullptr) const;
179         void successf(json_object *obj, const char *info, ...) const;
180
181         void fail(const char *status = "failed", const char *info = nullptr) const;
182         void failf(const char *status, const char *info, ...) const;
183
184         void *context_get() const;
185
186         void context_set(void *context, void (*free_context)(void*)) const;
187
188         void *context(void *(*create_context)(), void (*free_context)(void*)) const;
189
190         template < class T > T *context() const;
191
192         void context_clear() const;
193
194         void addref() const;
195
196         void unref() const;
197
198         void session_close() const;
199
200         bool session_set_LOA(unsigned level) const;
201
202         stored store() const;
203
204         bool subscribe(const event &event) const;
205
206         bool unsubscribe(const event &event) const;
207
208         void subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result), void *closure) const;
209
210         void subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, afb_req req), void *closure) const;
211
212         template <class T> void subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result), T *closure) const;
213
214         bool subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const;
215
216         void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const;
217
218         void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const;
219
220         bool has_permission(const char *permission) const;
221
222         char *get_application_id() const;
223 };
224
225 /*************************************************************************/
226 /* effective declaration of classes                                      */
227 /*************************************************************************/
228 /////////////////////////////////////////////////////////////////////////////////////////////////////
229 /////////////////////////////////////////////////////////////////////////////////////////////////////
230 /////////////////////////////////////////////////////////////////////////////////////////////////////
231 /////////////////////////////////////////////////////////////////////////////////////////////////////
232 /////////////////////////////////////////////////////////////////////////////////////////////////////
233 /////////////////////////////////////////////////////////////////////////////////////////////////////
234 /////////////////////////////////////////////////////////////////////////////////////////////////////
235 /////////////////////////////////////////////////////////////////////////////////////////////////////
236 /////////////////////////////////////////////////////////////////////////////////////////////////////
237 /////////////////////////////////////////////////////////////////////////////////////////////////////
238 /////////////////////////////////////////////////////////////////////////////////////////////////////
239 /////////////////////////////////////////////////////////////////////////////////////////////////////
240 /////////////////////////////////////////////////////////////////////////////////////////////////////
241 /////////////////////////////////////////////////////////////////////////////////////////////////////
242 /////////////////////////////////////////////////////////////////////////////////////////////////////
243 /////////////////////////////////////////////////////////////////////////////////////////////////////
244
245
246 /*************************************************************************/
247 /* effective declaration of classes                                      */
248 /*************************************************************************/
249
250 /* events */
251 inline event::event(const struct afb_event &e) : event_(e) { }
252 inline event::event(const event &other) : event_(other.event_) { }
253 inline event &event::operator=(const event &other) { event_ = other.event_; return *this; }
254
255 inline event::operator const struct afb_event&() const { return event_; }
256
257 inline event::operator bool() const { return is_valid(); }
258 inline bool event::is_valid() const { return afb_event_is_valid(event_); } 
259
260 inline void event::invalidate() { event_.itf = NULL; event_.closure = NULL; }
261
262 inline int event::broadcast(json_object *object) const { return afb_event_broadcast(event_, object); } 
263 inline int event::push(json_object *object) const { return afb_event_push(event_, object); }
264
265 inline void event::unref() { afb_event_unref(event_); invalidate(); }
266 inline void event::addref() { afb_event_addref(event_); }
267 inline const char *event::name() const { return afb_event_name(event_); }
268
269 /* args */
270 inline arg::arg(const struct afb_arg &a) : arg_(a) {}
271 inline arg::arg(const arg &other) : arg_(other.arg_) {}
272 inline arg &arg::operator=(const arg &other) { arg_ = other.arg_; return *this; }
273
274 inline arg::operator const struct afb_arg&() const { return arg_; }
275
276 inline bool arg::has_name() const { return !!arg_.name; }
277 inline bool arg::has_value() const { return !!arg_.value; }
278 inline bool arg::has_path() const { return !!arg_.path; }
279
280 inline const char *arg::name() const { return arg_.name; }
281 inline const char *arg::value() const { return arg_.value; }
282 inline const char *arg::path() const { return arg_.path; }
283
284 /* req(uests)s */
285
286 inline req::stored::stored(struct afb_stored_req *sr) : sreq_(sr) {}
287
288 inline req::stored::stored(const req::stored &other) : sreq_(other.sreq_) {}
289
290 inline req::stored &req::stored::operator =(const req::stored &other) { sreq_ = other.sreq_; return *this; }
291
292 inline req req::stored::unstore() const { return req(afb_daemon_unstore_req_v2(sreq_)); }
293
294
295 inline req::req(const struct afb_req &r) : req_(r) {}
296 inline req::req(const req &other) : req_(other.req_) {}
297 inline req &req::operator=(const req &other) { req_ = other.req_; return *this; }
298
299 inline req::operator const struct afb_req&() const { return req_; }
300
301 inline req::operator bool() const { return !!afb_req_is_valid(req_); }
302 inline bool req::is_valid() const { return !!afb_req_is_valid(req_); }
303
304 inline arg req::get(const char *name) const { return arg(afb_req_get(req_, name)); }
305
306 inline const char *req::value(const char *name) const { return afb_req_value(req_, name); }
307
308 inline const char *req::path(const char *name) const { return afb_req_path(req_, name); }
309
310 inline json_object *req::json() const { return afb_req_json(req_); }
311
312 inline void req::success(json_object *obj, const char *info) const { afb_req_success(req_, obj, info); }
313 inline void req::successf(json_object *obj, const char *info, ...) const
314 {
315         va_list args;
316         va_start(args, info);
317         afb_req_success_v(req_, obj, info, args);
318         va_end(args);
319 }
320
321 inline void req::fail(const char *status, const char *info) const { afb_req_fail(req_, status, info); }
322 inline void req::failf(const char *status, const char *info, ...) const
323 {
324         va_list args;
325         va_start(args, info);
326         afb_req_fail_v(req_, status, info, args);
327         va_end(args);
328 }
329
330 inline void *req::context_get() const { return afb_req_context_get(req_); }
331
332 inline void req::context_set(void *context, void (*free_context)(void*)) const { afb_req_context_set(req_, context, free_context); }
333
334 inline void *req::context(void *(*create_context)(), void (*free_context)(void*)) const { return afb_req_context(req_, create_context, free_context); }
335
336 template < class T >
337 inline T *req::context() const
338 {
339         T* (*creater)() = [](){return new T();};
340         void (*freer)(T*) = [](T*t){delete t;};
341         return reinterpret_cast<T*>(afb_req_context(req_,
342                         reinterpret_cast<void *(*)()>(creater),
343                         reinterpret_cast<void (*)(void*)>(freer)));
344 }
345
346 inline void req::context_clear() const { afb_req_context_clear(req_); }
347
348 inline void req::addref() const { afb_req_addref(req_); }
349
350 inline void req::unref() const { afb_req_unref(req_); }
351
352 inline void req::session_close() const { afb_req_session_close(req_); }
353
354 inline bool req::session_set_LOA(unsigned level) const { return !!afb_req_session_set_LOA(req_, level); }
355
356 inline req::stored req::store() const { return stored(afb_req_store_v2(req_)); }
357
358 inline bool req::subscribe(const event &event) const { return !afb_req_subscribe(req_, event); }
359
360 inline bool req::unsubscribe(const event &event) const { return !afb_req_unsubscribe(req_, event); }
361
362 inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result), void *closure) const
363 {
364         afb_req_subcall(req_, api, verb, args, callback, closure);
365 }
366
367 inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, struct afb_req req), void *closure) const
368 {
369         afb_req_subcall_req(req_, api, verb, args, callback, closure);
370 }
371
372 template <class T>
373 inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result), T *closure) const
374 {
375         afb_req_subcall(req_, api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*)>(callback), reinterpret_cast<void*>(closure));
376 }
377
378 inline bool req::subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const
379 {
380         return !!afb_req_subcall_sync(req_, api, verb, args, &result);
381 }
382
383 inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const
384 {
385         req_.itf->vverbose(req_.closure, level, file, line, func, fmt, args);
386 }
387
388 inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const
389 {
390         va_list args;
391         va_start(args, fmt);
392         req_.itf->vverbose(req_.closure, level, file, line, func, fmt, args);
393         va_end(args);
394 }
395
396 inline bool req::has_permission(const char *permission) const
397 {
398         return bool(req_.itf->has_permission(req_.closure, permission));
399 }
400
401 inline char *req::get_application_id() const
402 {
403         return req_.itf->get_application_id(req_.closure);
404 }
405
406 /* commons */
407 inline struct sd_event *get_event_loop()
408         { return afb_daemon_get_event_loop_v2(); }
409
410 inline struct sd_bus *get_system_bus()
411         { return afb_daemon_get_system_bus_v2(); }
412
413 inline struct sd_bus *get_user_bus()
414         { return afb_daemon_get_user_bus_v2(); }
415
416 inline int broadcast_event(const char *name, json_object *object)
417         { return afb_daemon_broadcast_event_v2(name, object); }
418
419 inline event make_event(const char *name)
420         { return afb_daemon_make_event_v2(name); }
421
422 inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args)
423         { afb_daemon_verbose_v2(level, file, line, func, fmt, args); }
424
425 inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...)
426         { va_list args; va_start(args, fmt); verbose(level, file, line, func, fmt, args); va_end(args); }
427
428 inline int rootdir_get_fd()
429         { return afb_daemon_rootdir_get_fd_v2(); }
430
431 inline int rootdir_open_locale_fd(const char *filename, int flags, const char *locale)
432         { return afb_daemon_rootdir_open_locale_v2(filename, flags, locale); }
433
434 inline int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
435         { return afb_daemon_queue_job_v2(callback, argument, group, timeout); }
436
437 inline int require_api(const char *apiname, bool initialized)
438         { return afb_daemon_require_api_v2(apiname, int(initialized)); }
439
440 inline int rename_api(const char *apiname)
441         { return afb_daemon_rename_api_v2(apiname); }
442
443 inline int verbosity()
444         { return afb_get_verbosity(); }
445
446 inline bool wants_errors()
447         { return afb_verbose_error(); }
448
449 inline bool wants_warnings()
450         { return afb_verbose_warning(); }
451
452 inline bool wants_notices()
453         { return afb_verbose_notice(); }
454
455 inline bool wants_infos()
456         { return afb_verbose_info(); }
457
458 inline bool wants_debugs()
459         { return afb_verbose_debug(); }
460
461 inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result), void *closure)
462 {
463         afb_service_call(api, verb, args, callback, closure);
464 }
465
466 template <class T>
467 inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, int iserror, struct json_object *result), T *closure)
468 {
469         afb_service_call(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*)>(callback), reinterpret_cast<void*>(closure));
470 }
471
472 inline bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result)
473 {
474         return !!afb_service_call_sync(api, verb, args, &result);
475 }
476
477 /*************************************************************************/
478 /* declaration of the binding's authorization s                          */
479 /*************************************************************************/
480
481 constexpr afb_auth auth_no()
482 {
483         afb_auth r = { afb_auth_No, 0, 0};
484         r.type = afb_auth_No;
485         return r;
486 }
487
488 constexpr afb_auth auth_yes()
489 {
490         afb_auth r = { afb_auth_No, 0, 0};
491         r.type = afb_auth_Yes;
492         return r;
493 }
494
495 constexpr afb_auth auth_token()
496 {
497         afb_auth r = { afb_auth_No, 0, 0};
498         r.type = afb_auth_Token;
499         return r;
500 }
501
502 constexpr afb_auth auth_LOA(unsigned loa)
503 {
504         afb_auth r = { afb_auth_No, 0, 0};
505         r.type = afb_auth_LOA;
506         r.loa = loa;
507         return r;
508 }
509
510 constexpr afb_auth auth_permission(const char *permission)
511 {
512         afb_auth r = { afb_auth_No, 0, 0};
513         r.type = afb_auth_Permission;
514         r.text = permission;
515         return r;
516 }
517
518 constexpr afb_auth auth_not(const afb_auth *other)
519 {
520         afb_auth r = { afb_auth_No, 0, 0};
521         r.type = afb_auth_Not;
522         r.first = other;
523         return r;
524 }
525
526 constexpr afb_auth auth_not(const afb_auth &other)
527 {
528         return auth_not(&other);
529 }
530
531 constexpr afb_auth auth_or(const afb_auth *first, const afb_auth *next)
532 {
533         afb_auth r = { afb_auth_No, 0, 0};
534         r.type = afb_auth_Or;
535         r.first = first;
536         r.next = next;
537         return r;
538 }
539
540 constexpr afb_auth auth_or(const afb_auth &first, const afb_auth &next)
541 {
542         return auth_or(&first, &next);
543 }
544
545 constexpr afb_auth auth_and(const afb_auth *first, const afb_auth *next)
546 {
547         afb_auth r = { afb_auth_No, 0, 0};
548         r.type = afb_auth_And;
549         r.first = first;
550         r.next = next;
551         return r;
552 }
553
554 constexpr afb_auth auth_and(const afb_auth &first, const afb_auth &next)
555 {
556         return auth_and(&first, &next);
557 }
558
559 constexpr afb_verb_v2 verb(const char *name, void (*callback)(afb_req), const char *info = nullptr, unsigned session = 0, const afb_auth *auth = nullptr)
560 {
561         afb_verb_v2 r = { 0, 0, 0, 0, 0 };
562         r.verb = name;
563         r.callback = callback;
564         r.info = info;
565         r.session = session;
566         r.auth = auth;
567         return r;
568 }
569
570 constexpr afb_verb_v2 verbend()
571 {
572         afb_verb_v2 r = { 0, 0, 0, 0, 0 };
573         r.verb = nullptr;
574         r.callback = nullptr;
575         r.info = nullptr;
576         r.session = 0;
577         r.auth = nullptr;
578         return r;
579 }
580
581 const afb_binding_v2 binding(const char *name, const struct afb_verb_v2 *verbs, const char *info = nullptr, int (*init)() = nullptr, const char *specification = nullptr, void (*onevent)(const char*, struct json_object*) = nullptr, bool noconcurrency = false, int (*preinit)() = nullptr)
582 {
583         afb_binding_v2 r = { 0, 0, 0, 0, 0, 0, 0, 0 };
584         r.api = name;
585         r.specification = specification;
586         r.info = info;
587         r.verbs = verbs;
588         r.preinit = preinit;
589         r.init = init;
590         r.onevent = onevent;
591         r.noconcurrency = noconcurrency ? 1 : 0;
592         return r;
593 };
594
595 /*************************************************************************/
596 /***                         E N D                                     ***/
597 /*************************************************************************/
598 }