2 * Copyright (C) 2016-2019 "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.
26 #ifndef AFB_BINDING_VERSION
27 # define AFB_BINDING_VERSION 3
30 /* check the version */
31 #if AFB_BINDING_VERSION < 3
32 # error "AFB_BINDING_VERSION must be at least 3"
35 /* get C definitions of bindings */
37 #include <afb/afb-binding.h>
41 /*************************************************************************/
42 /* pre-declaration of classes */
43 /*************************************************************************/
49 /*************************************************************************/
50 /* declaration of functions */
51 /*************************************************************************/
53 int broadcast_event(const char *name, json_object *object = nullptr);
55 event make_event(const char *name);
57 void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args);
59 void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...);
63 int rootdir_open_locale_fd(const char *filename, int flags, const char *locale = nullptr);
65 int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout);
67 int require_api(const char *apiname, bool initialized = true);
69 int add_alias(const char *apiname, const char *aliasname);
74 bool wants_warnings();
79 void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result, afb_api_t api), void *closure);
81 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, afb_api_t api), T *closure);
83 bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result);
85 /*************************************************************************/
86 /* effective declaration of classes */
87 /*************************************************************************/
96 event(const event &other);
99 event &operator=(const event &other);
100 event &operator=(event &&other);
102 operator afb_event_t() const;
103 afb_event_t operator->() const;
105 operator bool() const;
106 bool is_valid() const;
108 int broadcast(json_object *object) const;
109 int push(json_object *object) const;
113 const char *name() const;
122 arg(const struct afb_arg &a);
123 arg(const arg &other);
124 arg &operator=(const arg &other);
126 operator const struct afb_arg&() const;
128 bool has_name() const;
129 bool has_value() const;
130 bool has_path() const;
132 const char *name() const;
133 const char *value() const;
134 const char *path() const;
145 req(const req &other);
146 req &operator=(const req &other);
148 operator afb_req_t() const;
149 afb_req_t operator->() const;
151 operator bool() const;
152 bool is_valid() const;
154 arg get(const char *name) const;
156 const char *value(const char *name) const;
158 const char *path(const char *name) const;
160 json_object *json() const;
162 void reply(json_object *obj = nullptr, const char *error = nullptr, const char *info = nullptr) const;
163 void replyf(json_object *obj, const char *error, const char *info, ...) const;
164 void replyv(json_object *obj, const char *error, const char *info, va_list args) const;
166 void success(json_object *obj = nullptr, const char *info = nullptr) const;
167 void successf(json_object *obj, const char *info, ...) const;
168 void successv(json_object *obj, const char *info, va_list args) const;
170 void fail(const char *error = "failed", const char *info = nullptr) const;
171 void failf(const char *error, const char *info, ...) const;
172 void failv(const char *error, const char *info, va_list args) const;
174 template < class T > T *context() const;
180 void session_close() const;
182 bool session_set_LOA(unsigned level) const;
184 bool subscribe(const event &event) const;
186 bool unsubscribe(const event &event) const;
188 void subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, afb_req_t req), void *closure) const;
189 template <class T> void subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result, afb_req_t req), T *closure) const;
191 bool subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const;
193 void subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(void *closure, json_object *object, const char *error, const char *info, afb_req_t req), void *closure) const;
195 template <class T> void subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(T *closure, json_object *object, const char *error, const char *info, afb_req_t req), T *closure) const;
197 bool subcallsync(const char *api, const char *verb, json_object *args, int flags, struct json_object *&object, char *&error, char *&info) const;
199 void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const;
201 void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const;
203 bool has_permission(const char *permission) const;
205 char *get_application_id() const;
209 json_object *get_client_info() const;
212 /*************************************************************************/
213 /* effective declaration of classes */
214 /*************************************************************************/
215 /////////////////////////////////////////////////////////////////////////////////////////////////////
216 /////////////////////////////////////////////////////////////////////////////////////////////////////
217 /////////////////////////////////////////////////////////////////////////////////////////////////////
218 /////////////////////////////////////////////////////////////////////////////////////////////////////
219 /////////////////////////////////////////////////////////////////////////////////////////////////////
220 /////////////////////////////////////////////////////////////////////////////////////////////////////
221 /////////////////////////////////////////////////////////////////////////////////////////////////////
222 /////////////////////////////////////////////////////////////////////////////////////////////////////
223 /////////////////////////////////////////////////////////////////////////////////////////////////////
224 /////////////////////////////////////////////////////////////////////////////////////////////////////
225 /////////////////////////////////////////////////////////////////////////////////////////////////////
226 /////////////////////////////////////////////////////////////////////////////////////////////////////
227 /////////////////////////////////////////////////////////////////////////////////////////////////////
228 /////////////////////////////////////////////////////////////////////////////////////////////////////
229 /////////////////////////////////////////////////////////////////////////////////////////////////////
230 /////////////////////////////////////////////////////////////////////////////////////////////////////
233 /*************************************************************************/
234 /* effective declaration of classes */
235 /*************************************************************************/
238 inline event::event() : event_{nullptr} { }
239 inline event::event(afb_event_t e) : event_{e} { }
240 inline event::event(event &&other) : event_{other.event_} { other.event_ = nullptr; }
241 inline event::event(const event &other) : event_{other.event_} { addref(); }
242 inline event::~event() { unref(); }
243 inline event &event::operator=(const event &other) { event_ = other.event_; return *this; }
244 inline event &event::operator=(event &&other) { event_ = other.event_; other.event_ = nullptr; return *this;}
246 inline event::operator afb_event_t() const { return event_; }
247 inline afb_event_t event::operator->() const { return event_; }
249 inline event::operator bool() const { return is_valid(); }
250 inline bool event::is_valid() const { return afb_event_is_valid(event_); }
252 inline int event::broadcast(json_object *object) const { return afb_event_broadcast(event_, object); }
253 inline int event::push(json_object *object) const { return afb_event_push(event_, object); }
255 inline void event::unref() { if (event_) { afb_event_unref(event_); } event_ = nullptr; }
256 inline void event::addref() { afb_event_addref(event_); }
257 inline const char *event::name() const { return afb_event_name(event_); }
260 inline arg::arg(const struct afb_arg &a) : arg_(a) {}
261 inline arg::arg(const arg &other) : arg_(other.arg_) {}
262 inline arg &arg::operator=(const arg &other) { arg_ = other.arg_; return *this; }
264 inline arg::operator const struct afb_arg&() const { return arg_; }
266 inline bool arg::has_name() const { return !!arg_.name; }
267 inline bool arg::has_value() const { return !!arg_.value; }
268 inline bool arg::has_path() const { return !!arg_.path; }
270 inline const char *arg::name() const { return arg_.name; }
271 inline const char *arg::value() const { return arg_.value; }
272 inline const char *arg::path() const { return arg_.path; }
277 inline req::req(afb_req_t r) : req_(r) {}
278 inline req::req(const req &other) : req_(other.req_) {}
279 inline req &req::operator=(const req &other) { req_ = other.req_; return *this; }
281 inline req::operator afb_req_t() const { return req_; }
282 inline afb_req_t req::operator->() const { return req_; }
284 inline req::operator bool() const { return is_valid(); }
285 inline bool req::is_valid() const { return afb_req_is_valid(req_); }
287 inline arg req::get(const char *name) const { return arg(afb_req_get(req_, name)); }
289 inline const char *req::value(const char *name) const { return afb_req_value(req_, name); }
291 inline const char *req::path(const char *name) const { return afb_req_path(req_, name); }
293 inline json_object *req::json() const { return afb_req_json(req_); }
295 inline void req::reply(json_object *obj, const char *error, const char *info) const { afb_req_reply(req_, obj, error, info); }
296 inline void req::replyv(json_object *obj, const char *error, const char *info, va_list args) const { afb_req_reply_v(req_, obj, error, info, args); }
297 inline void req::replyf(json_object *obj, const char *error, const char *info, ...) const
300 va_start(args, info);
301 replyv(obj, error, info, args);
305 inline void req::success(json_object *obj, const char *info) const { reply(obj, nullptr, info); }
306 inline void req::successv(json_object *obj, const char *info, va_list args) const { replyv(obj, nullptr, info, args); }
307 inline void req::successf(json_object *obj, const char *info, ...) const
310 va_start(args, info);
311 successv(obj, info, args);
315 inline void req::fail(const char *error, const char *info) const { reply(nullptr, error, info); }
316 inline void req::failv(const char *error, const char *info, va_list args) const { replyv(nullptr, error, info, args); }
317 inline void req::failf(const char *error, const char *info, ...) const
320 va_start(args, info);
321 failv(error, info, args);
326 inline T *req::context() const
328 T* (*creater)(void*) = [](){return new T();};
329 void (*freer)(T*) = [](T*t){delete t;};
330 return reinterpret_cast<T*>(afb_req_context(req_, 0,
331 reinterpret_cast<void *(*)(void*)>(creater),
332 reinterpret_cast<void (*)(void*)>(freer), nullptr));
335 inline void req::addref() const { afb_req_addref(req_); }
337 inline void req::unref() const { afb_req_unref(req_); }
339 inline void req::session_close() const { afb_req_session_close(req_); }
341 inline bool req::session_set_LOA(unsigned level) const { return !afb_req_session_set_LOA(req_, level); }
343 inline bool req::subscribe(const event &event) const { return !afb_req_subscribe(req_, event); }
345 inline bool req::unsubscribe(const event &event) const { return !afb_req_unsubscribe(req_, event); }
347 inline void req::subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(void *closure, json_object *result, const char *error, const char *info, afb_req_t req), void *closure) const
349 afb_req_subcall(req_, api, verb, args, flags, callback, closure);
353 inline void req::subcall(const char *api, const char *verb, json_object *args, int flags, void (*callback)(T *closure, json_object *result, const char *error, const char *info, afb_req_t req), T *closure) const
355 subcall(api, verb, args, flags, reinterpret_cast<void(*)(void*,json_object*,const char*,const char*,afb_req_t)>(callback), reinterpret_cast<void*>(closure));
358 inline bool req::subcallsync(const char *api, const char *verb, json_object *args, int flags, struct json_object *&object, char *&error, char *&info) const
360 return !afb_req_subcall_sync(req_, api, verb, args, flags, &object, &error, &info);
363 inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result, afb_req_t req), void *closure) const
365 afb_req_subcall_legacy(req_, api, verb, args, callback, closure);
369 inline void req::subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result, afb_req_t req), T *closure) const
371 subcall(api, verb, args, reinterpret_cast<void(*)(void*,int,json_object*,afb_req_t)>(callback), reinterpret_cast<void*>(closure));
374 inline bool req::subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const
376 return !afb_req_subcall_sync_legacy(req_, api, verb, args, &result);
379 inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const
381 afb_req_verbose(req_, level, file, line, func, fmt, args);
384 inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const
388 afb_req_verbose(req_, level, file, line, func, fmt, args);
392 inline bool req::has_permission(const char *permission) const
394 return bool(afb_req_has_permission(req_, permission));
397 inline char *req::get_application_id() const
399 return afb_req_get_application_id(req_);
402 inline int req::get_uid() const
404 return afb_req_get_uid(req_);
407 inline json_object *req::get_client_info() const
409 return afb_req_get_client_info(req_);
413 inline int broadcast_event(const char *name, json_object *object)
414 { return afb_daemon_broadcast_event(name, object); }
416 inline event make_event(const char *name)
417 { return afb_daemon_make_event(name); }
419 inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args)
420 { afb_daemon_verbose(level, file, line, func, fmt, args); }
422 inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...)
423 { va_list args; va_start(args, fmt); verbose(level, file, line, func, fmt, args); va_end(args); }
425 inline int rootdir_get_fd()
426 { return afb_daemon_rootdir_get_fd(); }
428 inline int rootdir_open_locale_fd(const char *filename, int flags, const char *locale)
429 { return afb_daemon_rootdir_open_locale(filename, flags, locale); }
431 inline int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout)
432 { return afb_daemon_queue_job(callback, argument, group, timeout); }
434 inline int require_api(const char *apiname, bool initialized)
435 { return afb_daemon_require_api(apiname, int(initialized)); }
437 inline int add_alias(const char *apiname, const char *aliasname)
438 { return afb_daemon_add_alias(apiname, aliasname); }
441 { return afb_get_logmask(); }
443 inline bool wants_errors()
444 { return AFB_SYSLOG_MASK_WANT_ERROR(logmask()); }
446 inline bool wants_warnings()
447 { return AFB_SYSLOG_MASK_WANT_WARNING(logmask()); }
449 inline bool wants_notices()
450 { return AFB_SYSLOG_MASK_WANT_NOTICE(logmask()); }
452 inline bool wants_infos()
453 { return AFB_SYSLOG_MASK_WANT_INFO(logmask()); }
455 inline bool wants_debugs()
456 { return AFB_SYSLOG_MASK_WANT_DEBUG(logmask()); }
458 inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, struct json_object *result, const char *error, const char *info, afb_api_t api), void *closure)
460 afb_service_call(api, verb, args, callback, closure);
464 inline void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, struct json_object *result, const char *error, const char *info, afb_api_t api), T *closure)
466 afb_service_call(api, verb, args, reinterpret_cast<void(*)(void*,json_object*,const char*, const char*,afb_api_t)>(callback), reinterpret_cast<void*>(closure));
469 inline bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result, char *&error, char *&info)
471 return !!afb_service_call_sync(api, verb, args, &result, &error, &info);
474 /*************************************************************************/
475 /* declaration of the binding's authorization s */
476 /*************************************************************************/
478 constexpr afb_auth auth_no()
480 afb_auth r = { afb_auth_No, 0, 0};
481 r.type = afb_auth_No;
485 constexpr afb_auth auth_yes()
487 afb_auth r = { afb_auth_No, 0, 0};
488 r.type = afb_auth_Yes;
492 constexpr afb_auth auth_token()
494 afb_auth r = { afb_auth_No, 0, 0};
495 r.type = afb_auth_Token;
499 constexpr afb_auth auth_LOA(unsigned loa)
501 afb_auth r = { afb_auth_No, 0, 0};
502 r.type = afb_auth_LOA;
507 constexpr afb_auth auth_permission(const char *permission)
509 afb_auth r = { afb_auth_No, 0, 0};
510 r.type = afb_auth_Permission;
515 constexpr afb_auth auth_not(const afb_auth *other)
517 afb_auth r = { afb_auth_No, 0, 0};
518 r.type = afb_auth_Not;
523 constexpr afb_auth auth_not(const afb_auth &other)
525 return auth_not(&other);
528 constexpr afb_auth auth_or(const afb_auth *first, const afb_auth *next)
530 afb_auth r = { afb_auth_No, 0, 0};
531 r.type = afb_auth_Or;
537 constexpr afb_auth auth_or(const afb_auth &first, const afb_auth &next)
539 return auth_or(&first, &next);
542 constexpr afb_auth auth_and(const afb_auth *first, const afb_auth *next)
544 afb_auth r = { afb_auth_No, 0, 0};
545 r.type = afb_auth_And;
551 constexpr afb_auth auth_and(const afb_auth &first, const afb_auth &next)
553 return auth_and(&first, &next);
556 constexpr afb_verb_t verb(
558 void (*callback)(afb_req_t),
559 const char *info = nullptr,
560 uint16_t session = 0,
561 const afb_auth *auth = nullptr,
563 void *vcbdata = nullptr
566 afb_verb_t r = { 0, 0, 0, 0, 0, 0, 0 };
568 r.callback = callback;
572 r.glob = (unsigned)glob;
577 void __attribute__((weak)) __afb__verb__cb__for__global__(afb_req_t r)
580 void (*callback)(req);
582 vcbdata = afb_req_get_vcbdata(r);
583 callback = reinterpret_cast<void(*)(req)>(vcbdata);
587 constexpr afb_verb_t verb(
589 void (&callback)(req),
590 const char *info = nullptr,
591 uint16_t session = 0,
592 const afb_auth *auth = nullptr,
594 void *vcbdata = nullptr
599 __afb__verb__cb__for__global__,
608 constexpr afb_verb_t verbend()
610 afb_verb_t r = verb(nullptr, nullptr);
614 constexpr afb_binding_t binding(
616 const afb_verb_t *verbs,
617 const char *info = nullptr,
618 int (*init)(afb_api_t) = nullptr,
619 const char *specification = nullptr,
620 void (*onevent)(afb_api_t, const char*, struct json_object*) = nullptr,
621 bool noconcurrency = false,
622 int (*preinit)(afb_api_t) = nullptr,
623 void *userdata = nullptr
626 afb_binding_t r = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
628 r.specification = specification;
634 r.noconcurrency = noconcurrency ? 1 : 0;
635 r.userdata = userdata;
639 /*************************************************************************/
641 /*************************************************************************/