/* * Copyright (C) 2016, 2017 "IoT.bzh" * Author: José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include /* ensure version */ #ifndef AFB_BINDING_VERSION # define AFB_BINDING_VERSION 2 #endif /* check the version */ #if AFB_BINDING_VERSION < 2 # error "AFB_BINDING_VERSION must be at least 2" #endif /* get C definitions of bindings */ extern "C" { #include "afb-binding.h" } namespace afb { /*************************************************************************/ /* pre-declaration of classes */ /*************************************************************************/ class arg; class event; class req; class stored_req; /*************************************************************************/ /* declaration of functions */ /*************************************************************************/ struct sd_event *get_event_loop(); struct sd_bus *get_system_bus(); struct sd_bus *get_user_bus(); int broadcast_event(const char *name, json_object *object = nullptr); event make_event(const char *name); void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args); void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...); int rootdir_get_fd(); int rootdir_open_locale_fd(const char *filename, int flags, const char *locale = nullptr); int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout); int require_api(const char *apiname, bool initialized = true); int rename_api(const char *apiname); int verbosity(); bool wants_errors(); bool wants_warnings(); bool wants_notices(); bool wants_infos(); bool wants_debugs(); void call(const char *api, const char *verb, struct json_object *args, void (*callback)(void*closure, int iserror, struct json_object *result), void *closure); template void call(const char *api, const char *verb, struct json_object *args, void (*callback)(T*closure, int iserror, struct json_object *result), T *closure); bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result); /*************************************************************************/ /* effective declaration of classes */ /*************************************************************************/ /* events */ class event { struct afb_event event_; public: event() { event_.itf = nullptr; event_.closure = nullptr; } event(const struct afb_event &e); event(const event &other); event &operator=(const event &other); operator const struct afb_event&() const; operator bool() const; bool is_valid() const; void invalidate(); int broadcast(json_object *object) const; int push(json_object *object) const; void unref(); void addref(); const char *name() const; }; /* args */ class arg { struct afb_arg arg_; public: arg() = delete; arg(const struct afb_arg &a); arg(const arg &other); arg &operator=(const arg &other); operator const struct afb_arg&() const; bool has_name() const; bool has_value() const; bool has_path() const; const char *name() const; const char *value() const; const char *path() const; }; /* req(uest) */ class req { struct afb_req req_; public: class stored { struct afb_stored_req *sreq_; friend class req; stored() = delete; stored(struct afb_stored_req *sr); public: stored(const stored &other); stored &operator =(const stored &other); req unstore() const; }; class stored; public: req() = delete; req(const struct afb_req &r); req(const req &other); req &operator=(const req &other); operator const struct afb_req&() const; operator bool() const; bool is_valid() const; arg get(const char *name) const; const char *value(const char *name) const; const char *path(const char *name) const; json_object *json() const; void success(json_object *obj = nullptr, const char *info = nullptr) const; void successf(json_object *obj, const char *info, ...) const; void fail(const char *status = "failed", const char *info = nullptr) const; void failf(const char *status, const char *info, ...) const; void *context_get() const; void context_set(void *context, void (*free_context)(void*)) const; void *context(void *(*create_context)(), void (*free_context)(void*)) const; template < class T > T *context() const; void context_clear() const; void addref() const; void unref() const; void session_close() const; bool session_set_LOA(unsigned level) const; stored store() const; bool subscribe(const event &event) const; bool unsubscribe(const event &event) const; void subcall(const char *api, const char *verb, json_object *args, void (*callback)(void *closure, int iserror, json_object *result), void *closure) const; 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; template void subcall(const char *api, const char *verb, json_object *args, void (*callback)(T *closure, int iserror, json_object *result), T *closure) const; bool subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const; void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const; void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const; bool has_permission(const char *permission) const; char *get_application_id() const; }; /*************************************************************************/ /* effective declaration of classes */ /*************************************************************************/ ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// /*************************************************************************/ /* effective declaration of classes */ /*************************************************************************/ /* events */ inline event::event(const struct afb_event &e) : event_(e) { } inline event::event(const event &other) : event_(other.event_) { } inline event &event::operator=(const event &other) { event_ = other.event_; return *this; } inline event::operator const struct afb_event&() const { return event_; } inline event::operator bool() const { return is_valid(); } inline bool event::is_valid() const { return afb_event_is_valid(event_); } inline void event::invalidate() { event_.itf = NULL; event_.closure = NULL; } inline int event::broadcast(json_object *object) const { return afb_event_broadcast(event_, object); } inline int event::push(json_object *object) const { return afb_event_push(event_, object); } inline void event::unref() { afb_event_unref(event_); invalidate(); } inline void event::addref() { afb_event_addref(event_); } inline const char *event::name() const { return afb_event_name(event_); } /* args */ inline arg::arg(const struct afb_arg &a) : arg_(a) {} inline arg::arg(const arg &other) : arg_(other.arg_) {} inline arg &arg::operator=(const arg &other) { arg_ = other.arg_; return *this; } inline arg::operator const struct afb_arg&() const { return arg_; } inline bool arg::has_name() const { return !!arg_.name; } inline bool arg::has_value() const { return !!arg_.value; } inline bool arg::has_path() const { return !!arg_.path; } inline const char *arg::name() const { return arg_.name; } inline const char *arg::value() const { return arg_.value; } inline const char *arg::path() const { return arg_.path; } /* req(uests)s */ inline req::stored::stored(struct afb_stored_req *sr) : sreq_(sr) {} inline req::stored::stored(const req::stored &other) : sreq_(other.sreq_) {} inline req::stored &req::stored::operator =(const req::stored &other) { sreq_ = other.sreq_; return *this; } inline req req::stored::unstore() const { return req(afb_daemon_unstore_req_v2(sreq_)); } inline req::req(const struct afb_req &r) : req_(r) {} inline req::req(const req &other) : req_(other.req_) {} inline req &req::operator=(const req &other) { req_ = other.req_; return *this; } inline req::operator const struct afb_req&() const { return req_; } inline req::operator bool() const { return !!afb_req_is_valid(req_); } inline bool req::is_valid() const { return !!afb_req_is_valid(req_); } inline arg req::get(const char *name) const { return arg(afb_req_get(req_, name)); } inline const char *req::value(const char *name) const { return afb_req_value(req_, name); } inline const char *req::path(const char *name) const { return afb_req_path(req_, name); } inline json_object *req::json() const { return afb_req_json(req_); } inline void req::success(json_object *obj, const char *info) const { afb_req_success(req_, obj, info); } inline void req::successf(json_object *obj, const char *info, ...) const { va_list args; va_start(args, info); afb_req_success_v(req_, obj, info, args); va_end(args); } inline void req::fail(const char *status, const char *info) const { afb_req_fail(req_, status, info); } inline void req::failf(const char *status, const char *info, ...) const { va_list args; va_start(args, info); afb_req_fail_v(req_, status, info, args); va_end(args); } inline void *req::context_get() const { return afb_req_context_get(req_); } inline void req::context_set(void *context, void (*free_context)(void*)) const { afb_req_context_set(req_, context, free_context); } inline void *req::context(void *(*create_context)(), void (*free_context)(void*)) const { return afb_req_context(req_, create_context, free_context); } template < class T > inline T *req::context() const { T* (*creater)() = [](){return new T();}; void (*freer)(T*) = [](T*t){delete t;}; return reinterpret_cast(afb_req_context(req_, reinterpret_cast(creater), reinterpret_cast(freer))); } inline void req::context_clear() const { afb_req_context_clear(req_); } inline void req::addref() const { afb_req_addref(req_); } inline void req::unref() const { afb_req_unref(req_); } inline void req::session_close() const { afb_req_session_close(req_); } inline bool req::session_set_LOA(unsigned level) const { return !!afb_req_session_set_LOA(req_, level); } inline req::stored req::store() const { return stored(afb_req_store_v2(req_)); } inline bool req::subscribe(const event &event) const { return !afb_req_subscribe(req_, event); } inline bool req::unsubscribe(const event &event) const { return !afb_req_unsubscribe(req_, event); } 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 { afb_req_subcall(req_, api, verb, args, callback, closure); } 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 { afb_req_subcall_req(req_, api, verb, args, callback, closure); } template 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 { afb_req_subcall(req_, api, verb, args, reinterpret_cast(callback), reinterpret_cast(closure)); } inline bool req::subcallsync(const char *api, const char *verb, json_object *args, struct json_object *&result) const { return !!afb_req_subcall_sync(req_, api, verb, args, &result); } inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) const { req_.itf->vverbose(req_.closure, level, file, line, func, fmt, args); } inline void req::verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) const { va_list args; va_start(args, fmt); req_.itf->vverbose(req_.closure, level, file, line, func, fmt, args); va_end(args); } inline bool req::has_permission(const char *permission) const { return bool(req_.itf->has_permission(req_.closure, permission)); } inline char *req::get_application_id() const { return req_.itf->get_application_id(req_.closure); } /* commons */ inline struct sd_event *get_event_loop() { return afb_daemon_get_event_loop_v2(); } inline struct sd_bus *get_system_bus() { return afb_daemon_get_system_bus_v2(); } inline struct sd_bus *get_user_bus() { return afb_daemon_get_user_bus_v2(); } inline int broadcast_event(const char *name, json_object *object) { return afb_daemon_broadcast_event_v2(name, object); } inline event make_event(const char *name) { return afb_daemon_make_event_v2(name); } inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, va_list args) { afb_daemon_verbose_v2(level, file, line, func, fmt, args); } inline void verbose(int level, const char *file, int line, const char * func, const char *fmt, ...) { va_list args; va_start(args, fmt); verbose(level, file, line, func, fmt, args); va_end(args); } inline int rootdir_get_fd() { return afb_daemon_rootdir_get_fd_v2(); } inline int rootdir_open_locale_fd(const char *filename, int flags, const char *locale) { return afb_daemon_rootdir_open_locale_v2(filename, flags, locale); } inline int queue_job(void (*callback)(int signum, void *arg), void *argument, void *group, int timeout) { return afb_daemon_queue_job_v2(callback, argument, group, timeout); } inline int require_api(const char *apiname, bool initialized) { return afb_daemon_require_api_v2(apiname, int(initialized)); } inline int rename_api(const char *apiname) { return afb_daemon_rename_api_v2(apiname); } inline int verbosity() { return afb_get_verbosity(); } inline bool wants_errors() { return afb_verbose_error(); } inline bool wants_warnings() { return afb_verbose_warning(); } inline bool wants_notices() { return afb_verbose_notice(); } inline bool wants_infos() { return afb_verbose_info(); } inline bool wants_debugs() { return afb_verbose_debug(); } 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) { afb_service_call(api, verb, args, callback, closure); } template 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) { afb_service_call(api, verb, args, reinterpret_cast(callback), reinterpret_cast(closure)); } inline bool callsync(const char *api, const char *verb, struct json_object *args, struct json_object *&result) { return !!afb_service_call_sync(api, verb, args, &result); } /*************************************************************************/ /* declaration of the binding's authorization s */ /*************************************************************************/ constexpr afb_auth auth_no() { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_No; return r; } constexpr afb_auth auth_yes() { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_Yes; return r; } constexpr afb_auth auth_token() { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_Token; return r; } constexpr afb_auth auth_LOA(unsigned loa) { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_LOA; r.loa = loa; return r; } constexpr afb_auth auth_permission(const char *permission) { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_Permission; r.text = permission; return r; } constexpr afb_auth auth_not(const afb_auth *other) { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_Not; r.first = other; return r; } constexpr afb_auth auth_not(const afb_auth &other) { return auth_not(&other); } constexpr afb_auth auth_or(const afb_auth *first, const afb_auth *next) { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_Or; r.first = first; r.next = next; return r; } constexpr afb_auth auth_or(const afb_auth &first, const afb_auth &next) { return auth_or(&first, &next); } constexpr afb_auth auth_and(const afb_auth *first, const afb_auth *next) { afb_auth r = { afb_auth_No, 0, 0}; r.type = afb_auth_And; r.first = first; r.next = next; return r; } constexpr afb_auth auth_and(const afb_auth &first, const afb_auth &next) { return auth_and(&first, &next); } constexpr afb_verb_v2 verb(const char *name, void (*callback)(afb_req), const char *info = nullptr, unsigned session = 0, const afb_auth *auth = nullptr) { afb_verb_v2 r = { 0, 0, 0, 0, 0 }; r.verb = name; r.callback = callback; r.info = info; r.session = session; r.auth = auth; return r; } constexpr afb_verb_v2 verbend() { afb_verb_v2 r = { 0, 0, 0, 0, 0 }; r.verb = nullptr; r.callback = nullptr; r.info = nullptr; r.session = 0; r.auth = nullptr; return r; } 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) { afb_binding_v2 r = { 0, 0, 0, 0, 0, 0, 0, 0 }; r.api = name; r.specification = specification; r.info = info; r.verbs = verbs; r.preinit = preinit; r.init = init; r.onevent = onevent; r.noconcurrency = noconcurrency ? 1 : 0; return r; }; /*************************************************************************/ /*** E N D ***/ /*************************************************************************/ }