1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
5 * Copyright 2019 Samsung Electronics Co., Ltd
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
30 #include <type_traits>
31 #include <unordered_map>
37 #include <dali/devel-api/adaptor-framework/atspi-accessibility.h>
38 #include <dali/internal/accessibility/tizen-wayland/atspi/accessibility-optional.h>
40 #define ATSPI_PREFIX_PATH "/org/a11y/atspi/accessible/"
41 #define ATSPI_NULL_PATH "/org/a11y/atspi/null"
50 struct DALI_ADAPTOR_API DBusWrapper
52 virtual ~DBusWrapper() = default;
54 enum class ConnectionType
60 #define DEFINE_TYPE(name, eldbus_name, unref_call) \
61 struct name { virtual ~name() = default; }; \
62 using name ## Ptr = std::shared_ptr<name>; \
63 using name ## WeakPtr = std::weak_ptr<name>; \
65 DEFINE_TYPE(Connection, Eldbus_Connection, )
66 DEFINE_TYPE(MessageIter, Eldbus_Message_Iter, eldbus_message_iter_container_close(Value))
67 DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref(Value))
68 DEFINE_TYPE(Proxy, Eldbus_Proxy, eldbus_proxy_unref(Value))
69 DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref(Value))
70 DEFINE_TYPE(Pending, Eldbus_Pending, )
71 DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
74 virtual ConnectionPtr eldbus_address_connection_get_impl(const std::string& addr) = 0;
76 #define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
77 virtual void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) = 0; \
78 virtual bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) = 0;
79 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
80 eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
82 eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
83 eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
84 eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
85 eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
86 eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
87 eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
88 eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
89 eldbus_message_iter_arguments_append_impl_basic(double, d)
90 eldbus_message_iter_arguments_append_impl_basic(bool, b)
91 eldbus_message_iter_arguments_append_impl_basic_impl(const std::string&, std::string, s)
92 eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath&, ObjectPath, o)
94 #undef eldbus_message_iter_arguments_append_impl_basic
95 #undef eldbus_message_iter_arguments_append_impl_basic_impl
97 virtual MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr& it, int type, const std::string& sig) = 0;
98 virtual MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr& it, int type) = 0;
99 virtual MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr& it, bool write) = 0;
100 virtual MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr& proxy, const std::string& funcName) = 0;
101 virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr& proxy, const MessagePtr& msg) = 0;
102 virtual bool eldbus_message_error_get_impl(const MessagePtr& msg, std::string& name, std::string& text) = 0;
103 virtual std::string eldbus_message_signature_get_impl(const MessagePtr& msg) = 0;
105 using SendCallback = std::function<void(const MessagePtr & msg)>;
106 virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr& proxy, const MessagePtr& msg, const SendCallback& callback) = 0;
107 virtual std::string eldbus_proxy_interface_get_impl(const ProxyPtr&) = 0;
108 virtual void eldbus_proxy_signal_handler_add_impl(const ProxyPtr& proxy, const std::string& member, const std::function<void(const MessagePtr&)>& cb) = 0;
109 virtual std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr& iter) = 0;
110 virtual MessagePtr eldbus_message_method_return_new_impl(const MessagePtr& msg) = 0;
111 virtual MessagePtr eldbus_message_error_new_impl(const MessagePtr& msg, const std::string& err, const std::string& txt) = 0;
112 virtual PendingPtr eldbus_connection_send_impl(const ConnectionPtr& conn, const MessagePtr& msg) = 0;
113 virtual MessagePtr eldbus_message_signal_new_impl(const std::string& path, const std::string& iface, const std::string& name) = 0;
114 virtual MessagePtr eldbus_message_ref_impl(const MessagePtr& msg) = 0;
115 virtual ConnectionPtr eldbus_connection_get_impl(ConnectionType type) = 0;
116 virtual std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr& conn) = 0;
117 virtual ObjectPtr eldbus_object_get_impl(const ConnectionPtr& conn, const std::string& bus, const std::string& path) = 0;
118 virtual ProxyPtr eldbus_proxy_get_impl(const ObjectPtr& obj, const std::string& interface) = 0;
119 virtual ProxyPtr eldbus_proxy_copy_impl(const ProxyPtr& ptr) = 0;
124 struct char_ptr_deleter
126 void operator()(char* p)
131 std::vector< std::unique_ptr< char, char_ptr_deleter > > storage;
133 const char* add(const char* txt)
135 auto ptr = strdup(txt);
136 storage.push_back(std::unique_ptr< char, char_ptr_deleter >(ptr));
137 return storage.back().get();
139 const char* add(const std::string& txt)
141 return add(txt.c_str());
147 static std::atomic< unsigned int > LastId;
148 unsigned int id = ++LastId;
153 std::string memberName;
154 std::vector< std::pair<std::string, std::string> > in, out; // _Eldbus_Arg_Info
155 std::function< DBusWrapper::MessagePtr(const DBusWrapper::MessagePtr & msg) > callback;
160 std::string memberName;
161 std::vector< std::pair<std::string, std::string> > args;
162 unsigned int uniqueId;
166 CallId setterId, getterId;
167 std::string memberName, typeSignature;
168 std::function< std::string(const DBusWrapper::MessagePtr & src, const DBusWrapper::MessageIterPtr & dst) > getCallback, setCallback;
174 SignalId() = default;
175 SignalId(CallId id) : id(id) {}
177 virtual void add_interface_impl(bool fallback, const std::string& pathName,
178 const ConnectionPtr& connection,
179 std::vector<std::function<void()>>& destructors,
180 const std::string& interfaceName,
181 std::vector< MethodInfo >& dscrMethods,
182 std::vector< PropertyInfo >& dscrProperties,
183 std::vector< SignalInfo >& dscrSignals) = 0;
184 virtual void add_property_changed_event_listener_impl(const ProxyPtr& proxy, const std::string& interface, const std::string& name, std::function< void(const _Eina_Value*) > cb) = 0;
185 static DBusWrapper* Installed();
186 static void Install(std::unique_ptr<DBusWrapper>);
188 StringStorage Strings;
192 enum class MethodType {
193 Method, Getter, Setter
198 template <> struct hash<std::tuple<std::string, std::string, std::string>> {
199 size_t operator () (const std::tuple<std::string, std::string, std::string>& a) const {
200 auto a1 = std::hash<std::string>()(std::get<0>(a));
201 auto a2 = std::hash<std::string>()(std::get<1>(a));
202 auto a3 = std::hash<std::string>()(std::get<2>(a));
204 v = (v * 11400714819323198485llu) + a2;
205 v = (v * 11400714819323198485llu) + a3;
209 template <> struct hash<std::tuple<std::string, std::string, std::string, detail::MethodType>> {
210 size_t operator () (const std::tuple<std::string, std::string, std::string, detail::MethodType>& a) const {
211 auto a1 = std::hash<std::string>()(std::get<0>(a));
212 auto a2 = std::hash<std::string>()(std::get<1>(a));
213 auto a3 = std::hash<std::string>()(std::get<2>(a));
214 auto a4 = static_cast<size_t>(std::get<3>(a));
216 v = (v * 11400714819323198485llu) + a2;
217 v = (v * 11400714819323198485llu) + a3;
218 v = (v * 11400714819323198485llu) + a4;
222 template <> struct hash<std::tuple<std::string, std::string, unsigned int>> {
223 size_t operator () (const std::tuple<std::string, std::string, unsigned int>& a) const {
224 auto a1 = std::hash<std::string>()(std::get<0>(a));
225 auto a2 = std::hash<std::string>()(std::get<1>(a));
226 auto a3 = std::get<2>(a);
228 v = (v * 11400714819323198485llu) + a2;
229 v = (v * 11400714819323198485llu) + a3;
236 template <typename T> struct DBusSigImpl { enum { value = 0, end = 0 }; };
237 template <typename T> struct DBusSig { enum { value = DBusSigImpl<typename std::decay<T>::type>::value, end = DBusSigImpl<typename std::decay<T>::type>::end }; };
238 template <typename T, typename Q, size_t I, size_t S> struct IndexFromTypeTupleImpl {
239 enum { value = std::is_same<typename std::decay<typename std::tuple_element<I, T>::type>::type, Q>::value ? I : IndexFromTypeTupleImpl<T, Q, I + 1, S>::value };
241 template <typename T, typename Q, size_t S> struct IndexFromTypeTupleImpl<T, Q, S, S> { enum { value = S }; };
242 template <typename T, typename Q> struct IndexFromTypeTuple {
243 enum { value = IndexFromTypeTupleImpl<T, typename std::decay<Q>::type, 0, std::tuple_size<T>::value>::value };
245 template <typename T, typename = void> struct Encoder;
246 template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple;
250 template <> struct DBusSigImpl<uint8_t> { enum { value = 'y', end = 0 }; };
251 template <> struct DBusSigImpl<uint16_t> { enum { value = 'q', end = 0 }; };
252 template <> struct DBusSigImpl<uint32_t> { enum { value = 'u', end = 0 }; };
253 template <> struct DBusSigImpl<uint64_t> { enum { value = 't', end = 0 }; };
254 template <> struct DBusSigImpl<int16_t> { enum { value = 'n', end = 0 }; };
255 template <> struct DBusSigImpl<int32_t> { enum { value = 'i', end = 0 }; };
256 template <> struct DBusSigImpl<int64_t> { enum { value = 'x', end = 0 }; };
257 template <> struct DBusSigImpl<double> { enum { value = 'd', end = 0 }; };
258 template <> struct DBusSigImpl<bool> { enum { value = 'b', end = 0 }; };
259 template <> struct DBusSigImpl<std::string> { enum { value = 's', end = 0 }; };
260 template <> struct DBusSigImpl<ObjectPath> { enum { value = 'o', end = 0 }; };
264 #define DBUS_DEBUG( ... ) \
267 DBus::debugPrint( __FILE__, __LINE__, __VA_ARGS__ ); \
270 #define DBUS_W DBusWrapper::Installed()
273 * @brief Template based, single file, wrapper library around eldbus for DBUS based communication.
275 * Main motivation was missing asynchronous calls in AT-SPI library and difficulties,
276 * when using eldbus from C++.
279 * - takes care of marshalling arguments to and from DBUS calls.
280 * - allows synchronous and asynchronous calls.
281 * - allows synchronous and asynchronous listeners on signals.
282 * - manages all involved objects' lifetimes.
283 * - errors are passed as optional-alike objects, no exceptions are used.
284 * - allows setting additional debug-print function for more details about
287 * DBUS's method signatures (and expected return values) are specified as template argument,
288 * using functor syntax. For example:
290 * auto dbus = DBusClient{ ... };
291 * auto v = dbus.method<std::tuple<int, float>(float, float, std::string)>("foo").call(1.0f, 2.0f, "qwe");
293 * means (synchronous) call on dbus object, which takes three arguments (thus making call signature \b dds)
294 * of types float, float and string (float will be automatically converted to double).
295 * Expected return value is std::tuple<int, float>, which gives signature <B>(id)</B> - std::tuple acts
296 * as struct container. Returned value v will be of type ValueOrError<std::tuple<int, float>>.\n
297 * Slightly different (asynchronous) example:
299 * auto dbus = DBusClient{ ... };
300 * std::function<void(ValueOrError<int, float>)> callback;
301 * dbus.method<ValueOrError<int, float>(float, float, std::string)>("foo").asyncCall(callback, 1.0f, 2.0f, "qwe");
303 * Now the call takes the same arguments and has the same signature. But expected values are different -
304 * now the signature is simply \b id. ValueOrError acts in this case as placeholder for list of values,
305 * which DBUS allows as return data. The call itself is asynchronous - instead of expecting reply
306 * you need to pass a callback, which will be called either with received data and error message.
308 * Library is not thread-safe, the same object shouldn't be called from different threads without
309 * synchronization. There's no guarantee, that callbacks will be executed on the same thread.
316 class DBusInterfaceDescription;
319 * @brief Formats debug message and calls debug printer (if any) with it
321 void debugPrint(const char* file, size_t line, const char* format, ...);
324 * @brief Sets debug printer callback, which will be called with debug messages
326 * Callback will be called in various moments of DBus activity. First value passed to callback
327 * is pointer to text, second it's length. Text is ended with 0 (not counted towards it's size),
328 * user can safely printf it.
330 void setDebugPrinter(std::function< void(const char*, size_t) >);
337 Error(std::string msg) : message(std::move(msg))
339 assert(!message.empty());
349 * @brief Value representing data, that came from DBUS or error message
351 * Object of this class either helds series of values (of types ARGS...)
352 * or error message. This object will be true in boolean context, if has data
353 * and false, if an error occured.
354 * It's valid to create ValueOrError object with empty argument list or void:
357 * ValueOrError<void> v2;
359 * Both mean the same - ValueOrError containing no real data and being a marker,
360 * wherever operation successed or failed and containing possible error message.
362 template < typename... ARGS >
367 * @brief Empty constructor. Valid only, if all ARGS types are default constructible.
369 ValueOrError() = default;
372 * @brief Value constructor.
374 * This will be initialized as success with passed in values.
376 ValueOrError(ARGS... t) : value(std::move(t)...) {}
379 * @brief Alternative Value constructor.
381 * This will be initialized as success with passed in values.
383 ValueOrError(std::tuple< ARGS... > t) : value(std::move(t)) {}
386 * @brief Error constructor. This will be initialized as failure with given error message.
388 ValueOrError(Error e) : error(std::move(e))
390 assert(!error.message.empty());
394 * @brief bool operator.
396 * Returns true, if operation was successful (getValues member is callable), or false
397 * when operation failed (getError is callable).
399 explicit operator bool() const
401 return error.message.empty();
405 * @brief Returns error message object.
407 * Returns object containing error message associated with the failed operation.
408 * Only callable, if operation actually failed, otherwise will assert.
410 const Error& getError() const
416 * @brief Returns modifiable tuple of held data.
418 * Returns reference to the internal tuple containing held data.
419 * User can modify (or move) data safely.
420 * Only callable, if operation actually successed, otherwise will assert.
422 std::tuple< ARGS... >& getValues()
429 * @brief Returns const tuple of held data.
431 * Returns const reference to the internal tuple containing held data.
432 * Only callable, if operation actually successed, otherwise will assert.
434 const std::tuple< ARGS... >& getValues() const
441 std::tuple< ARGS... > value;
451 ValueOrError() = default;
452 ValueOrError(std::tuple<> t) {}
453 ValueOrError(Error e) : error(std::move(e))
455 assert(!error.message.empty());
458 explicit operator bool() const
460 return error.message.empty();
462 const Error& getError() const
466 std::tuple<>& getValues()
469 static std::tuple<> t;
472 std::tuple<> getValues() const
483 class ValueOrError< void >
486 ValueOrError() = default;
487 ValueOrError(Success) {}
488 ValueOrError(Error e) : error(std::move(e))
490 assert(!error.message.empty());
493 explicit operator bool() const
495 return error.message.empty();
497 const Error& getError() const
501 std::tuple<>& getValues()
504 static std::tuple<> t;
507 std::tuple<> getValues() const
517 using ObjectPath = ObjectPath;
521 * @brief Class used to marshall DBUS's variant type
523 * Minimalistic class, that allows user to specify DBUS variant type
524 * as argument or return value. You need to pass real type hidden under variant as
525 * template type \b A. At this point library doesn't allow to expected one of few classes
526 * as return data in variant. So for example user can't specify method call, which on return
527 * expects DBUS variant holding either string or int.
529 template < typename A >
536 * @brief Namespace for private, internal functions and classes
540 template < typename T, typename = void >
542 template < typename... ARGS >
543 struct signature< std::tuple< ARGS... > >;
544 template < typename A, typename B >
545 struct signature< std::pair< A, B > >;
546 template < typename A >
547 struct signature< std::vector< A > >;
548 template < typename A, size_t N >
549 struct signature< std::array< A, N > >;
550 template < typename A, typename B >
551 struct signature< std::unordered_map< A, B > >;
552 template < typename A, typename B >
553 struct signature< std::map< A, B > >;
556 * @brief Signature class for marshalling uint8 type.
559 struct signature< uint8_t >
562 * @brief Returns name of type marshalled, for informative purposes
564 static std::string name()
570 * @brief Returns DBUS' signature of type marshalled
572 static std::string sig()
578 * @brief Marshals value v as marshalled type into message
580 static void set(const DBusWrapper::MessageIterPtr& iter, uint8_t v)
582 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
586 * @brief Marshals value from marshalled type into variable v
588 static bool get(const DBusWrapper::MessageIterPtr& iter, uint8_t& v)
590 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
595 * @brief Signature class for marshalling uint16 type.
598 struct signature< uint16_t >
601 * @brief Returns name of type marshalled, for informative purposes
603 static std::string name()
609 * @brief Returns DBUS' signature of type marshalled
611 static std::string sig()
617 * @brief Marshals value v as marshalled type into message
619 static void set(const DBusWrapper::MessageIterPtr& iter, uint16_t v)
621 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
625 * @brief Marshals value from marshalled type into variable v
627 static bool get(const DBusWrapper::MessageIterPtr& iter, uint16_t& v)
629 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
634 * @brief Signature class for marshalling uint32 type.
637 struct signature< uint32_t >
640 * @brief Returns name of type marshalled, for informative purposes
642 static std::string name()
648 * @brief Returns DBUS' signature of type marshalled
650 static std::string sig()
656 * @brief Marshals value v as marshalled type into message
658 static void set(const DBusWrapper::MessageIterPtr& iter, uint32_t v)
660 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
664 * @brief Marshals value from marshalled type into variable v
666 static bool get(const DBusWrapper::MessageIterPtr& iter, uint32_t& v)
668 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
673 * @brief Signature class for marshalling uint64 type.
676 struct signature< uint64_t >
679 * @brief Returns name of type marshalled, for informative purposes
681 static std::string name()
687 * @brief Returns DBUS' signature of type marshalled
689 static std::string sig()
695 * @brief Marshals value v as marshalled type into message
697 static void set(const DBusWrapper::MessageIterPtr& iter, uint64_t v)
699 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
703 * @brief Marshals value from marshalled type into variable v
705 static bool get(const DBusWrapper::MessageIterPtr& iter, uint64_t& v)
707 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
712 * @brief Signature class for marshalling int16 type.
715 struct signature< int16_t >
718 * @brief Returns name of type marshalled, for informative purposes
720 static std::string name()
726 * @brief Returns DBUS' signature of type marshalled
728 static std::string sig()
734 * @brief Marshals value v as marshalled type into message
736 static void set(const DBusWrapper::MessageIterPtr& iter, int16_t v)
738 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
742 * @brief Marshals value from marshalled type into variable v
744 static bool get(const DBusWrapper::MessageIterPtr& iter, int16_t& v)
746 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
751 * @brief Signature class for marshalling int32 type.
754 struct signature< int32_t >
757 * @brief Returns name of type marshalled, for informative purposes
759 static std::string name()
765 * @brief Returns DBUS' signature of type marshalled
767 static std::string sig()
773 * @brief Marshals value v as marshalled type into message
775 static void set(const DBusWrapper::MessageIterPtr& iter, int32_t v)
777 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
781 * @brief Marshals value from marshalled type into variable v
783 static bool get(const DBusWrapper::MessageIterPtr& iter, int32_t& v)
785 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
790 * @brief Signature class for marshalling int64 type.
793 struct signature< int64_t >
796 * @brief Returns name of type marshalled, for informative purposes
798 static std::string name()
804 * @brief Returns DBUS' signature of type marshalled
806 static std::string sig()
812 * @brief Marshals value v as marshalled type into message
814 static void set(const DBusWrapper::MessageIterPtr& iter, int64_t v)
816 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
820 * @brief Marshals value from marshalled type into variable v
822 static bool get(const DBusWrapper::MessageIterPtr& iter, int64_t& v)
824 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
829 * @brief Signature class for marshalling double type.
832 struct signature< double >
835 * @brief Returns name of type marshalled, for informative purposes
837 static std::string name()
843 * @brief Returns DBUS' signature of type marshalled
845 static std::string sig()
851 * @brief Marshals value v as marshalled type into message
853 static void set(const DBusWrapper::MessageIterPtr& iter, double v)
855 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
859 * @brief Marshals value from marshalled type into variable v
861 static bool get(const DBusWrapper::MessageIterPtr& iter, double& v)
863 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
867 * @brief Marshals value from marshalled type into variable v
869 static bool get(const DBusWrapper::MessageIterPtr& iter, float& v2)
872 auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
873 v2 = static_cast<float>(v);
879 * @brief Signature class for marshalling float type.
882 struct signature< float >
885 * @brief Returns name of type marshalled, for informative purposes
887 static std::string name()
893 * @brief Returns DBUS' signature of type marshalled
895 static std::string sig()
901 * @brief Marshals value v as marshalled type into message
903 static void set(const DBusWrapper::MessageIterPtr& iter, float v)
905 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
909 * @brief Marshals value from marshalled type into variable v
911 static bool get(const DBusWrapper::MessageIterPtr& iter, double& v)
913 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
917 * @brief Marshals value from marshalled type into variable v
919 static bool get(const DBusWrapper::MessageIterPtr& iter, float& v2)
922 auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
923 v2 = static_cast<float>(v);
929 * @brief Signature class for marshalling boolean type.
932 struct signature< bool >
935 * @brief Returns name of type marshalled, for informative purposes
937 static std::string name()
943 * @brief Returns DBUS' signature of type marshalled
945 static std::string sig()
951 * @brief Marshals value v as marshalled type into message
953 static void set(const DBusWrapper::MessageIterPtr& iter, bool v)
955 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
959 * @brief Marshals value from marshalled type into variable v
961 static bool get(const DBusWrapper::MessageIterPtr& iter, bool& v)
963 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
967 template < typename T >
968 struct signature< T, typename std::enable_if< std::is_enum< T >::value, void >::type >
971 * @brief Returns name of type marshalled, for informative purposes
973 static std::string name()
979 * @brief Returns DBUS' signature of type marshalled
981 static std::string sig()
983 return signature<typename std::underlying_type<T>::type>::sig();
987 * @brief Marshals value v as marshalled type into message
989 static void set(const DBusWrapper::MessageIterPtr& iter, T v)
991 signature<typename std::underlying_type<T>::type>::set(iter, static_cast<int64_t>(v));
995 * @brief Marshals value from marshalled type into variable v
997 static bool get(const DBusWrapper::MessageIterPtr& iter, T& v)
999 typename std::underlying_type<T>::type q = 0;
1000 if (!signature<typename std::underlying_type<T>::type>::get(iter, q))
1003 v = static_cast<T>(q);
1009 * @brief Signature class for marshalling string type.
1011 * Both (const) char * and std::string types are accepted as value to send.
1012 * Only std::string is accepted as value to receive.
1015 struct signature< std::string >
1018 * @brief Returns name of type marshalled, for informative purposes
1020 static std::string name()
1026 * @brief Returns DBUS' signature of type marshalled
1028 static std::string sig()
1034 * @brief Marshals value v as marshalled type into message
1036 static void set(const DBusWrapper::MessageIterPtr& iter, const std::string& v)
1038 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1042 * @brief Marshals value from marshalled type into variable v
1044 static bool get(const DBusWrapper::MessageIterPtr& iter, std::string& v)
1046 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1051 struct signature< ObjectPath >
1054 * @brief Returns name of type marshalled, for informative purposes
1056 static std::string name()
1062 * @brief Returns DBUS' signature of type marshalled
1064 static std::string sig()
1070 * @brief Marshals value v as marshalled type into message
1072 static void set(const DBusWrapper::MessageIterPtr& iter, const std::string& v)
1074 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1078 * @brief Marshals value v as marshalled type into message
1080 static void set(const DBusWrapper::MessageIterPtr& iter, const ObjectPath& v)
1082 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1086 * @brief Marshals value v as marshalled type into message
1088 static void set(const DBusWrapper::MessageIterPtr& iter, const char* v)
1090 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1094 * @brief Marshals value from marshalled type into variable v
1096 static bool get(const DBusWrapper::MessageIterPtr& iter, ObjectPath& v)
1098 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1102 * @brief Marshals value from marshalled type into variable v
1104 static bool get(const DBusWrapper::MessageIterPtr& iter, std::string& v)
1107 if (!DBUS_W->eldbus_message_iter_get_and_next_impl(iter, q)) return false;
1108 v = std::move(q.value);
1114 * @brief Signature class for marshalling (const) char * type.
1116 * Both (const) char * and std::string types are accepted as value to send.
1117 * You can't use (const) char * variable type to receive value.
1120 struct signature< char* >
1123 * @brief Returns name of type marshalled, for informative purposes
1125 static std::string name()
1131 * @brief Returns DBUS' signature of type marshalled
1133 static std::string sig()
1139 * @brief Marshals value v as marshalled type into message
1141 static void set(const DBusWrapper::MessageIterPtr& iter, const std::string& v)
1143 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1147 * @brief Marshals value v as marshalled type into message
1149 static void set(const DBusWrapper::MessageIterPtr& iter, const char* v)
1151 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, std::string{ v });
1155 template < size_t INDEX, typename A, typename... ARGS >
1156 struct signature_tuple_element_type_helper
1158 using type = typename signature_tuple_element_type_helper< INDEX - 1, ARGS... >::type;
1161 template < typename A, typename... ARGS >
1162 struct signature_tuple_element_type_helper< 0, A, ARGS... >
1168 * @brief Helper class to marshall tuples
1170 * This class marshals all elements of the tuple value starting at the index INDEX
1171 * and incrementing. This class recursively calls itself with increasing INDEX value
1172 * until INDEX is equal to SIZE, where recursive calling ends.
1174 template < size_t INDEX, size_t SIZE, typename... ARGS >
1175 struct signature_tuple_helper
1177 using current_type = typename signature_tuple_element_type_helper< INDEX, ARGS... >::type;
1180 * @brief Returns name of type marshalled, for informative purposes
1182 static std::string name()
1184 if (INDEX + 1 >= SIZE)
1185 return signature< current_type >::name();
1186 return signature< current_type >::name() + ", " + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::name();
1190 * @brief Returns DBUS' signature of type marshalled
1192 static std::string sig()
1194 return signature< current_type >::sig() + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::sig();
1198 * @brief Marshals value v as marshalled type into message
1200 static void set(const DBusWrapper::MessageIterPtr& iter, const std::tuple< ARGS... >& args)
1202 signature< current_type >::set(iter, std::get< INDEX >(args));
1203 signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::set(iter, args);
1207 * @brief Marshals value from marshalled type into variable v
1209 static bool get(const DBusWrapper::MessageIterPtr& iter, std::tuple< ARGS... >& args)
1211 return signature< current_type >::get(iter, std::get< INDEX >(args)) &&
1212 signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::get(iter, args);
1217 * @brief Helper class to marshall tuples
1219 * This class marks end of the tuple marshalling. Members of this class are called
1220 * when INDEX value is equal to SIZE.
1222 template < size_t SIZE, typename... ARGS >
1223 struct signature_tuple_helper< SIZE, SIZE, ARGS... >
1226 * @brief Returns name of type marshalled, for informative purposes
1228 static std::string name()
1234 * @brief Returns DBUS' signature of type marshalled
1236 static std::string sig()
1242 * @brief Marshals value v as marshalled type into message
1244 static void set(const DBusWrapper::MessageIterPtr& iter, const std::tuple< ARGS... >& args)
1249 * @brief Marshals value from marshalled type into variable v
1251 static bool get(const DBusWrapper::MessageIterPtr& iter, std::tuple< ARGS... >& args)
1258 * @brief Signature class for marshalling tuple of values
1260 * This class marshalls tuple of values. This represents
1261 * DBUS struct typle, encoded with character 'r'
1263 template < typename... ARGS >
1264 struct signature< std::tuple< ARGS... > >
1267 * @brief Returns name of type marshalled, for informative purposes
1269 static std::string name()
1271 return "tuple<" + signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::name() + ">";
1275 * @brief Returns DBUS' signature of type marshalled
1277 static std::string sig()
1279 return "(" + signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::sig() + ")";
1283 * @brief Marshals value v as marshalled type into message
1285 static void set(const DBusWrapper::MessageIterPtr& iter, const std::tuple< ARGS... >& args)
1287 auto entry = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'r', "");
1288 signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::set(entry, args);
1292 * @brief Marshals value from marshalled type into variable v
1294 static bool get(const DBusWrapper::MessageIterPtr& iter, std::tuple< ARGS... >& args)
1296 auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'r');
1297 if (!entry) return false;
1298 return signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::get(entry, args);
1303 * @brief Signature class for marshalling ValueOrError template type
1305 * ValueOrError template type is used to marshall list of values passed to
1306 * DBUS (or received from) at the "top" level. For example ss(s) is represented as
1307 * \code{.cpp} ValueOrError<std::string, std::string, std::tuple<std::string>> \endcode
1308 * While (ss(s)) is represented as
1309 * \code{.cpp} std::tuple<std::string, std::string, std::tuple<std::string>> \endcode
1311 * \code{.cpp} ValueOrError<std::tuple<std::string, std::string, std::tuple<std::string>>> \endcode
1313 template < typename... ARGS >
1314 struct signature< ValueOrError< ARGS... > >
1317 * @brief Returns name of type marshalled, for informative purposes
1319 static std::string name()
1321 return "ValueOrError<" + signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::name() + ">";
1325 * @brief Returns DBUS' signature of type marshalled
1327 static std::string sig()
1329 return signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::sig();
1333 * @brief Marshals value v as marshalled type into message
1335 static void set(const DBusWrapper::MessageIterPtr& iter, const ValueOrError< ARGS... >& args)
1337 signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::set(iter, args.getValues());
1341 * @brief Marshals value from marshalled type into variable v
1343 static bool get(const DBusWrapper::MessageIterPtr& iter, ValueOrError< ARGS... >& args)
1345 return signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::get(iter, args.getValues());
1350 * @brief Signature class for marshalling ValueOrError<void> type
1353 struct signature< ValueOrError< void > >
1356 * @brief Returns name of type marshalled, for informative purposes
1358 static std::string name()
1360 return "ValueOrError<void>";
1364 * @brief Returns DBUS' signature of type marshalled
1366 static std::string sig()
1372 * @brief Marshals value v as marshalled type into message
1374 static void set(const DBusWrapper::MessageIterPtr& iter, const ValueOrError< void >& args)
1379 * @brief Marshals value from marshalled type into variable v
1381 static bool get(const DBusWrapper::MessageIterPtr& iter, ValueOrError< void >& args)
1388 * @brief Signature class for marshalling ValueOrError<> type
1391 struct signature< ValueOrError<> >
1394 * @brief Returns name of type marshalled, for informative purposes
1396 static std::string name()
1398 return "ValueOrError<>";
1402 * @brief Returns DBUS' signature of type marshalled
1404 static std::string sig()
1410 * @brief Marshals value v as marshalled type into message
1412 static void set(const DBusWrapper::MessageIterPtr& iter, const ValueOrError<>& args)
1417 * @brief Marshals value from marshalled type into variable v
1419 static bool get(const DBusWrapper::MessageIterPtr& iter, ValueOrError<>& args)
1426 * @brief Signature class for marshalling pair of types
1428 template < typename A, typename B >
1429 struct signature< std::pair< A, B > >
1432 * @brief Returns name of type marshalled, for informative purposes
1434 static std::string name()
1436 return "pair<" + signature_tuple_helper< 0, 2, A, B >::name() + ">";
1440 * @brief Returns DBUS' signature of type marshalled
1442 static std::string sig()
1444 return "(" + signature_tuple_helper< 0, 2, A, B >::sig() + ")";
1448 * @brief Marshals value v as marshalled type into message
1450 static void set(const DBusWrapper::MessageIterPtr& iter, const std::pair< A, B >& ab, bool dictionary = false)
1452 auto entry = DBUS_W->eldbus_message_iter_container_new_impl(iter, dictionary ? 'e' : 'r', "");
1453 signature_tuple_helper< 0, 2, A, B >::set(entry, ab);
1457 * @brief Marshals value from marshalled type into variable v
1459 static bool get(const DBusWrapper::MessageIterPtr& iter, std::pair< A, B >& ab)
1461 auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'r');
1463 entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, '{');
1464 if (!entry) return false;
1467 std::tuple< A, B > ab_tmp;
1468 auto z = signature_tuple_helper< 0, 2, A, B >::get(entry, ab_tmp);
1471 ab.first = std::move(std::get< 0 >(ab_tmp));
1472 ab.second = std::move(std::get< 1 >(ab_tmp));
1479 * @brief Signature class for marshalling std::vector template type
1481 * This marshals container's content as DBUS a ascii character type code.
1483 template < typename A >
1484 struct signature< std::vector< A > >
1487 * @brief Returns name of type marshalled, for informative purposes
1489 static std::string name()
1491 return "vector<" + signature< A >::name() + ">";
1495 * @brief Returns DBUS' signature of type marshalled
1497 static std::string sig()
1499 return "a" + signature< A >::sig();
1503 * @brief Marshals value v as marshalled type into message
1505 static void set(const DBusWrapper::MessageIterPtr& iter, const std::vector< A >& v)
1507 auto lst = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'a', signature< A >::sig());
1511 signature< A >::set(lst, a);
1516 * @brief Marshals value from marshalled type into variable v
1518 static bool get(const DBusWrapper::MessageIterPtr& iter, std::vector< A >& v)
1520 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1521 if (!s) return false;
1524 while (signature< A >::get(s, a))
1525 v.push_back(std::move(a));
1532 * @brief Signature class for marshalling std::array template type
1534 * This marshals container's content as DBUS a ascii character type code.
1536 template < typename A, size_t N >
1537 struct signature< std::array< A, N > >
1540 * @brief Returns name of type marshalled, for informative purposes
1542 static std::string name()
1544 return "array<" + signature< A >::name() + ", " + std::to_string(N) + ">";
1548 * @brief Returns DBUS' signature of type marshalled
1550 static std::string sig()
1552 return "a" + signature< A >::sig();
1556 * @brief Marshals value v as marshalled type into message
1558 static void set(const DBusWrapper::MessageIterPtr& iter, const std::array< A, N >& v)
1560 auto lst = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'a', signature< A >::sig());
1564 signature< A >::set(lst, a);
1569 * @brief Marshals value from marshalled type into variable v
1571 static bool get(const DBusWrapper::MessageIterPtr& iter, std::array< A, N >& v)
1573 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1578 if (!signature< A >::get(s, a))
1586 * @brief Signature class for marshalling EldbusVariant type
1588 * This marshals variant's content as DBUS v ascii character type code.
1590 template < typename A >
1591 struct signature< EldbusVariant< A > >
1594 * @brief Returns name of type marshalled, for informative purposes
1596 static std::string name()
1598 return "variant<" + signature< A >::name() + ">";
1602 * @brief Returns DBUS' signature of type marshalled
1604 static std::string sig()
1610 * @brief Marshals value v as marshalled type into message
1612 static void set(const DBusWrapper::MessageIterPtr& iter, const EldbusVariant< A >& v)
1618 * @brief Marshals value v as marshalled type into message
1620 static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1622 auto var = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'v', signature< A >::sig());
1623 signature< A >::set(var, v);
1627 * @brief Marshals value from marshalled type into variable v
1629 static bool get(const DBusWrapper::MessageIterPtr& iter, EldbusVariant< A >& v)
1631 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'v');
1634 return signature< A >::get(s, v.value);
1639 * @brief Signature class for marshalling std::unordered_map template type
1641 * This marshals container's content as DBUS {} ascii character type code.
1642 * Note, that library doesnt check, if the key is basic type, as DBUS
1643 * specification mandates.
1644 * User can always exchange std::unordered_map for std::map and the reverse.
1645 * User can receive such values as std::vector of std::pair<key, value> values.
1646 * Order of such values is unspecified.
1648 template < typename A, typename B >
1649 struct signature< std::unordered_map< A, B > >
1652 * @brief Returns name of type marshalled, for informative purposes
1654 static std::string name()
1656 return "unordered_map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
1660 * @brief Returns DBUS' signature of type marshalled
1662 static std::string sig()
1664 return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
1668 * @brief Marshals value v as marshalled type into message
1670 static void set(const DBusWrapper::MessageIterPtr& iter, const std::unordered_map< A, B >& v)
1672 auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
1673 auto lst = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'a', sig);
1677 signature< std::pair< A, B > >::set(lst, a, true);
1682 * @brief Marshals value from marshalled type into variable v
1684 static bool get(const DBusWrapper::MessageIterPtr& iter, std::unordered_map< A, B >& v)
1686 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1690 std::pair< A, B > a;
1691 while (signature< std::pair< A, B > >::get(s, a))
1692 v.insert(std::move(a));
1698 * @brief Signature class for marshalling std::unordered_map template type
1700 * This marshals container's content as DBUS {} ascii character type code.
1701 * Note, that library doesnt check, if the key is basic type, as DBUS
1702 * specification mandates.
1703 * User can always exchange std::unordered_map for std::map and the reverse.
1704 * User can receive such values as std::vector of std::pair<key, value> values.
1705 * Order of such values is unspecified.
1707 template < typename A, typename B >
1708 struct signature< std::map< A, B > >
1711 * @brief Returns name of type marshalled, for informative purposes
1713 static std::string name()
1715 return "map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
1719 * @brief Returns DBUS' signature of type marshalled
1721 static std::string sig()
1723 return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
1727 * @brief Marshals value v as marshalled type into message
1729 static void set(const DBusWrapper::MessageIterPtr& iter, const std::map< A, B >& v)
1731 auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
1732 auto lst = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'a', sig);
1736 signature< std::pair< A, B > >::set(lst, a, true);
1741 * @brief Marshals value from marshalled type into variable v
1743 static bool get(const DBusWrapper::MessageIterPtr& iter, std::map< A, B >& v)
1745 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1748 std::pair< A, B > a;
1749 while (signature< std::pair< A, B > >::get(s, a))
1750 v.insert(std::move(a));
1756 * @brief Signature helper class for marshalling const reference types
1758 template < typename A >
1759 struct signature< const A& >
1762 * @brief Returns name of type marshalled, for informative purposes
1764 static std::string name()
1766 return "const " + signature< A >::name() + "&";
1770 * @brief Returns DBUS' signature of type marshalled
1772 static std::string sig()
1774 return signature< A >::sig();
1778 * @brief Marshals value v as marshalled type into message
1780 static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1782 signature< A >::set(iter, v);
1786 * @brief Marshals value from marshalled type into variable v
1788 static void get(const DBusWrapper::MessageIterPtr& iter, A& v)
1790 signature< A >::get(iter, v);
1795 * @brief Signature helper class for marshalling reference types
1797 template < typename A >
1798 struct signature< A& >
1801 * @brief Returns name of type marshalled, for informative purposes
1803 static std::string name()
1805 return signature< A >::name() + "&";
1809 * @brief Returns DBUS' signature of type marshalled
1811 static std::string sig()
1813 return signature< A >::sig();
1817 * @brief Marshals value v as marshalled type into message
1819 static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1821 signature< A >::set(iter, v);
1825 * @brief Marshals value from marshalled type into variable v
1827 static void get(const DBusWrapper::MessageIterPtr& iter, A& v)
1829 signature< A >::get(iter, v);
1834 * @brief Signature helper class for marshalling const types
1836 template < typename A >
1837 struct signature< const A >
1840 * @brief Returns name of type marshalled, for informative purposes
1842 static std::string name()
1844 return "const " + signature< A >::name();
1848 * @brief Returns DBUS' signature of type marshalled
1850 static std::string sig()
1852 return signature< A >::sig();
1856 * @brief Marshals value v as marshalled type into message
1858 static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1860 signature< A >::set(iter, v);
1864 * @brief Marshals value from marshalled type into variable v
1866 static void get(const DBusWrapper::MessageIterPtr& iter, A& v)
1868 signature< A >::get(iter, v);
1872 using CallId = DBusWrapper::CallId;
1874 template < typename ValueType >
1875 ValueType unpackValues(CallId callId, const DBusWrapper::MessagePtr& msg)
1877 auto iter = DBUS_W->eldbus_message_iter_get_impl(msg, false);
1882 if (!signature< ValueType >::get(iter, r))
1884 DBUS_DEBUG("ValueType is %s", signature< ValueType >::name().c_str());
1885 r = Error{ "call " + std::to_string(callId.id) + ": failed to unpack values, got signature '" +
1886 DBUS_W->eldbus_message_signature_get_impl(msg) + "', expected '" + signature< ValueType >::sig() + "'" };
1891 r = Error{ "call " + std::to_string(callId.id) + ": failed to get iterator" };
1896 inline void packValues_helper(const DBusWrapper::MessageIterPtr&) {}
1898 template < typename A, typename... ARGS >
1899 void packValues_helper(const DBusWrapper::MessageIterPtr& iter, A&& a, ARGS&&... r)
1901 signature< A >::set(iter, std::forward< A >(a));
1902 packValues_helper(iter, std::forward< ARGS >(r)...);
1905 template < typename... ARGS >
1906 void packValues(CallId callId, const DBusWrapper::MessagePtr& msg, ARGS&&... r)
1908 auto iter = DBUS_W->eldbus_message_iter_get_impl(msg, true);
1909 packValues_helper(iter, std::forward< ARGS >(r)...);
1912 template < typename >
1914 template < typename R, typename... ARGS >
1915 struct ReturnType< R(ARGS...) >
1920 template < typename R, typename... ARGS >
1921 struct ReturnType< std::function< R(ARGS...) > >
1931 template < int N, int... S >
1932 struct sequence_gen : sequence_gen< N - 1, N - 1, S... >
1936 template < int... S >
1937 struct sequence_gen< 0, S... >
1939 typedef sequence< S... > type;
1942 template < typename C, typename... ARGS >
1945 const std::function< C >& c;
1946 const std::tuple< ARGS... >& args;
1948 template < int... S >
1949 auto apply_2(sequence< S... >) const -> decltype(c(std::get< S >(args)...))
1951 return c(std::get< S >(args)...);
1953 auto apply_1() const -> decltype(apply_2(typename sequence_gen< sizeof...(ARGS) >::type()))
1955 return apply_2(typename sequence_gen< sizeof...(ARGS) >::type());
1959 template < typename C, typename A, typename... ARGS >
1960 struct apply_helper_2
1962 const std::function< C >& c;
1964 const std::tuple< ARGS... >& args;
1966 template < int... S >
1967 auto apply_2(sequence< S... >) const -> decltype(c(a, std::get< S >(args)...))
1969 return c(a, std::get< S >(args)...);
1971 auto apply_1() const -> decltype(apply_2(typename sequence_gen< sizeof...(ARGS) >::type()))
1973 return apply_2(typename sequence_gen< sizeof...(ARGS) >::type());
1977 template < typename C, typename... ARGS >
1978 auto apply(const std::function< C >& c, const std::tuple< ARGS... >& args) -> typename ReturnType< C >::type
1980 apply_helper< C, ARGS... > ah{ c, args };
1981 return ah.apply_1();
1984 template < typename C, typename D, typename... ARGS >
1985 auto apply(const std::function< C >& c, const D& d, const std::tuple< ARGS... >& args) -> typename ReturnType< C >::type
1987 apply_helper_2< C, D, ARGS... > ah{ c, d, args };
1988 return ah.apply_1();
1991 struct ConnectionState
1993 DBusWrapper::ConnectionPtr connection;
1994 DBusWrapper::ObjectPtr object;
1995 DBusWrapper::ProxyPtr proxy, propertiesProxy;
1998 template < typename RETTYPE, typename... ARGS >
1999 RETTYPE call(CallId callId, const ConnectionState& connectionState, bool property, const std::string& funcName, const ARGS&... args)
2001 const auto& proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
2004 DBUS_DEBUG("call %d: not initialized", callId.id);
2005 return Error{ "not initialized" };
2008 DBUS_DEBUG("call %d: calling '%s'", callId.id, funcName.c_str());
2009 auto msg = DBUS_W->eldbus_proxy_method_call_new_impl(proxy, funcName);
2012 DBUS_DEBUG("call %d: failed", callId.id);
2013 return Error{ "failed to create message" };
2016 detail::packValues(callId, msg, args...);
2017 auto reply = DBUS_W->eldbus_proxy_send_and_block_impl(proxy, msg);
2018 DBUS_DEBUG("call %d: calling '%s' done", callId.id, funcName.c_str());
2021 DBUS_DEBUG("call %d: failed", callId.id);
2022 return Error{ "eldbus returned null as reply" };
2024 std::string errname, errmsg;
2025 if (DBUS_W->eldbus_message_error_get_impl(reply, errname, errmsg))
2027 DBUS_DEBUG("call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str());
2028 return Error{ errname + ": " + errmsg };
2030 DBUS_DEBUG("call %d: got reply with signature '%s'", callId.id,
2031 DBUS_W->eldbus_message_signature_get_impl(reply).c_str());
2032 return detail::unpackValues< RETTYPE >(callId, reply);
2035 template < typename RETTYPE, typename... ARGS >
2036 void asyncCall(CallId callId, const ConnectionState& connectionState,
2037 bool property, const std::string& funcName,
2038 std::function< void(RETTYPE) > callback, const ARGS&... args)
2040 const auto& proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
2043 DBUS_DEBUG("call %d: not initialized", callId.id);
2044 callback(Error{ "not initialized" });
2048 auto msg = DBUS_W->eldbus_proxy_method_call_new_impl(proxy, funcName);
2051 DBUS_DEBUG("call %d: failed", callId.id);
2052 callback(Error{ "failed to create message" });
2056 detail::packValues(callId, msg, args...);
2057 auto pending = DBUS_W->eldbus_proxy_send_impl(proxy, msg, [callback, callId, proxy](const DBusWrapper::MessagePtr& reply) {
2058 DBUS_DEBUG("call %d: calling done", callId.id);
2061 DBUS_DEBUG("call %d: failed", callId.id);
2062 callback(Error{ "eldbus returned null as reply" });
2066 std::string errname, errmsg;
2067 if (DBUS_W->eldbus_message_error_get_impl(reply, errname, errmsg))
2069 DBUS_DEBUG("call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str());
2070 callback(Error{ errname + ": " + errmsg });
2074 DBUS_DEBUG("call %d: got reply with signature '%s'", callId.id,
2075 DBUS_W->eldbus_message_signature_get_impl(reply).c_str());
2076 callback(detail::unpackValues< RETTYPE >(callId, reply));
2083 DBUS_DEBUG("call %d: call sent", callId.id);
2087 DBUS_DEBUG("call %d: failed to send call", callId.id);
2088 callback(Error{ "failed to send call" });
2092 inline void displayDebugCallInfo(CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName)
2094 DBUS_DEBUG("call %d: %s iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str());
2097 inline void displayDebugCallInfoSignal(CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName)
2099 DBUS_DEBUG("call %d: %s signal iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str());
2102 inline void displayDebugCallInfoProperty(CallId callId, const std::string& funcName, std::string info, const std::string& interfaceName,
2103 const std::string& propertyName)
2105 DBUS_DEBUG("call %d: %s iname = %s pname = %s", callId.id, info.c_str(), interfaceName.c_str(), propertyName.c_str());
2108 using StringStorage = DBusWrapper::StringStorage;
2110 template < typename A, typename... ARGS >
2111 struct EldbusArgGenerator_Helper
2113 static void add(std::vector< std::pair<std::string, std::string> >& r)
2116 auto sig = signature< A >::sig();
2117 assert(!sig.empty());
2118 auto name = "p" + std::to_string(s + 1);
2119 r.push_back({ std::move(sig), std::move(name) });
2120 EldbusArgGenerator_Helper<ARGS...>::add(r);
2125 struct EldbusArgGenerator_Helper< void >
2127 static void add(std::vector< std::pair<std::string, std::string> >&)
2133 struct EldbusArgGenerator_Helper< ValueOrError< void >, void >
2135 static void add(std::vector< std::pair<std::string, std::string> >&)
2140 struct EldbusArgGenerator_Helper< ValueOrError<>, void >
2142 static void add(std::vector< std::pair<std::string, std::string> >&)
2147 template < typename... ARGS >
2148 struct EldbusArgGenerator_Helper< std::tuple< ARGS... > >
2150 static void add(std::vector< std::pair<std::string, std::string> >& r)
2152 EldbusArgGenerator_Helper< ARGS..., void >::add(r);
2156 template < typename RetType >
2157 struct dbus_interface_return_type_traits
2159 using type = ValueOrError< RetType >;
2162 template < typename... ARGS >
2163 struct dbus_interface_return_type_traits< ValueOrError< ARGS... > >
2165 using type = ValueOrError< ARGS... >;
2168 template < typename T >
2169 struct dbus_interface_traits;
2170 template < typename RetType, typename... ARGS >
2171 struct dbus_interface_traits< RetType(ARGS...) >
2173 using Ret = typename dbus_interface_return_type_traits< RetType >::type;
2174 using SyncCB = std::function< Ret(ARGS...) >;
2175 using AsyncCB = std::function< void(std::function< void(Ret) >, ARGS...) >;
2176 using VEArgs = ValueOrError< ARGS... >;
2179 template < typename T >
2180 struct EldbusArgGenerator_Args;
2181 template < typename RetType, typename... ARGS >
2182 struct EldbusArgGenerator_Args< RetType(ARGS...) >
2184 static std::string name()
2186 return signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::name();
2188 static std::vector< std::pair<std::string, std::string> > get()
2190 std::vector< std::pair<std::string, std::string> > tmp;
2191 EldbusArgGenerator_Helper< ARGS..., void >::add(tmp);
2196 template < typename T >
2197 struct EldbusArgGenerator_ReturnType;
2198 template < typename RetType, typename... ARGS >
2199 struct EldbusArgGenerator_ReturnType< RetType(ARGS...) >
2201 static std::string name()
2203 return signature< RetType >::name();
2205 static std::vector< std::pair<std::string, std::string> > get()
2207 std::vector< std::pair<std::string, std::string> > tmp;
2208 EldbusArgGenerator_Helper< RetType, void >::add(tmp);
2213 template < typename T >
2214 struct EldbusArgGenerator_ReturnType;
2215 template < typename... ARGS >
2216 struct EldbusArgGenerator_ReturnType< void(ARGS...) >
2218 static std::string name()
2222 static std::vector< std::pair<std::string, std::string> > get()
2230 using ConnectionType = DBusWrapper::ConnectionType;
2233 * @brief Class representing client's end of DBUS connection
2235 * Allows calling (synchronous and asynchronos) methods on selected interface
2236 * Allows (synchronous and asynchronos) setting / getting properties.
2237 * Allows registering signals.
2241 struct ConnectionInfo
2243 std::string interfaceName, busName, pathName;
2247 * @brief Default constructor, creates non-connected object.
2249 DBusClient() = default;
2252 * @brief Connects to dbus choosen by tp, using given arguments
2254 * @param bus_name name of the bus to connect to
2255 * @param path_name object's path
2256 * @param interface_name interface name
2258 DBusClient(std::string busName_, std::string pathName_, std::string interfaceName_,
2262 * @brief Connects to dbus using connection conn
2264 * @param bus_name name of the bus to connect to
2265 * @param path_name object's path
2266 * @param interface_name interface name
2267 * @param conn connection object from getDBusConnectionByType call
2269 DBusClient(std::string busName_, std::string pathName_, std::string interfaceName_,
2270 const DBusWrapper::ConnectionPtr& conn = {});
2273 * @brief Destructor object.
2275 * All signals added will be disconnected.
2276 * All asynchronous calls will be cancelled, their callback's will be called
2277 * with failure message.
2279 ~DBusClient() = default;
2280 DBusClient(const DBusClient&) = delete;
2281 DBusClient(DBusClient&&) = default;
2283 DBusClient& operator=(DBusClient&&) = default;
2284 DBusClient& operator=(const DBusClient&) = delete;
2287 * @brief bool operator
2289 * Returns true, if object is connected to DBUS
2291 explicit operator bool() const
2293 return bool(connectionState->proxy);
2297 * @brief Helper class for calling a method
2299 * Template type T defines both arguments sent to the method
2300 * and expected values. Receiving different values will be reported as
2301 * error. For example:
2302 * \code{.cpp} Method<int(float, float)> \endcode
2303 * defines method, which takes two arguments (two floats) and return
2304 * single value of type int.
2306 template < typename T >
2309 using RetType = typename detail::dbus_interface_traits< T >::Ret;
2310 const detail::ConnectionState& connectionState;
2311 std::string funcName;
2313 std::shared_ptr< ConnectionInfo > connectionInfo;
2316 * @brief Executes synchronous call on DBUS's method
2318 * The function returns ValueOrError<...> object, which
2319 * contains either received values or error message.
2321 * @param args arguments to pass to the method
2323 template < typename... ARGS >
2324 RetType call(const ARGS&... args)
2326 detail::CallId callId;
2327 detail::displayDebugCallInfo(callId, funcName, info, connectionInfo->interfaceName);
2328 return detail::call< RetType >(callId, connectionState, false, funcName, args...);
2332 * @brief Executes asynchronous call on DBUS's method
2334 * The function calls callback with either received values or error message.
2336 * @param callback callback functor, which will be called with return value(s) or error message
2337 * @param args arguments to pass to the method
2339 template < typename... ARGS >
2340 void asyncCall(std::function< void(RetType) > callback, const ARGS&... args)
2342 detail::CallId callId;
2343 detail::displayDebugCallInfo(callId, funcName, info, connectionInfo->interfaceName);
2344 detail::asyncCall< RetType >(callId, connectionState, false, funcName, std::move(callback), args...);
2349 * @brief Helper class for calling a property
2351 * Template type T defines type of the value hidden under property.
2352 * Note, that library automatically wraps both sent and received value into
2353 * DBUS's wrapper type.
2355 template < typename T >
2358 using RetType = typename detail::dbus_interface_return_type_traits< T >::type;
2359 using VariantRetType = typename detail::dbus_interface_return_type_traits< EldbusVariant< T > >::type;
2360 const detail::ConnectionState& connectionState;
2361 std::string propName;
2363 std::shared_ptr< ConnectionInfo > connectionInfo;
2366 * @brief executes synchronous get on property
2368 * The function returns ValueOrError<...> object, which
2369 * contains either received values or error message.
2373 detail::CallId callId;
2374 detail::displayDebugCallInfoProperty(callId, "Get", info, connectionInfo->interfaceName, propName);
2375 auto z = detail::call< VariantRetType >(callId, connectionState, true, "Get", connectionInfo->interfaceName, propName);
2377 return z.getError();
2378 return { std::get< 0 >(z.getValues()).value };
2382 * @brief executes asynchronous get on property
2384 * The function calls callback with either received values or error message.
2386 * @param callback callback functor, which will be called with return value(s) or error message
2388 void asyncGet(std::function< void(RetType) > callback)
2390 detail::CallId callId;
2391 detail::displayDebugCallInfoProperty(callId, "Get", info, connectionInfo->interfaceName, propName);
2392 auto cc = [callback](VariantRetType reply) {
2394 callback(std::move(std::get< 0 >(reply.getValues()).value));
2396 callback(reply.getError());
2398 detail::asyncCall< VariantRetType >(callId, connectionState, true, "Get", std::move(cc), connectionInfo->interfaceName, propName);
2402 * @brief executes synchronous set on property
2404 * The function returns ValueOrError<void> object, with
2405 * possible error message.
2407 ValueOrError< void > set(const T& r)
2409 detail::CallId callId;
2410 detail::displayDebugCallInfoProperty(callId, "Set", info, connectionInfo->interfaceName, propName);
2411 EldbusVariant< T > variantValue{ std::move(r) };
2412 return detail::call< ValueOrError< void > >(callId, connectionState, true, "Set", connectionInfo->interfaceName, propName, variantValue);
2416 * @brief executes asynchronous get on property
2418 * The function calls callback with either received values or error message.
2420 * @param callback callback functor, which will be called with return value(s) or error message
2422 void asyncSet(std::function< void(ValueOrError< void >) > callback, const T& r)
2424 detail::CallId callId;
2425 detail::displayDebugCallInfoProperty(callId, "Set", info, connectionInfo->interfaceName, propName);
2426 EldbusVariant< T > variantValue{ std::move(r) };
2427 detail::asyncCall< ValueOrError< void > >(callId, connectionState, true, "Set", std::move(callback), connectionInfo->interfaceName, propName, variantValue);
2432 * @brief Constructs Property<...> object for calling properties
2434 * The function constructs and returns proxy object for calling property.
2436 * @param propName property name to set and / or query
2438 template < typename PropertyType >
2439 Property< PropertyType > property(std::string propName)
2441 return Property< PropertyType >{*connectionState, std::move(propName), info, connectionInfo};
2445 * @brief Constructs Method<...> object for calling methods
2447 * The function constructs and returns proxy object for calling method.
2449 * @param funcName function name to call
2451 template < typename MethodType >
2452 Method< MethodType > method(std::string funcName)
2454 return Method< MethodType >{*connectionState, std::move(funcName), info, connectionInfo};
2458 * @brief Registers notification callback, when property has changed
2460 * The callback will be called with new value, when property's value has changed.
2461 * Note, that template type V must match expected type, otherwise undefined behavior will occur,
2462 * there's no check for this.
2464 template < typename V >
2465 void addPropertyChangedEvent(std::string propertyName, std::function< void(V) > callback)
2467 detail::CallId callId;
2468 detail::displayDebugCallInfoSignal(callId, propertyName, info, connectionInfo->interfaceName);
2469 DBUS_DEBUG("call %d: adding property", callId.id);
2470 auto& cI = this->connectionInfo;
2471 DBUS_W->add_property_changed_event_listener_impl(connectionState->proxy, cI->interfaceName, propertyName,
2472 [callback](const _Eina_Value* newValue) {
2474 if (!getFromEinaValue(newValue, &val))
2476 DBUS_DEBUG("unable to get property's value");
2484 * @brief Registers callback on the DBUS' signal
2486 * The function registers callback signalName. When signal comes, callback will be called.
2487 * Callback object will exists as long as signal is registered. You can unregister signal
2488 * by destroying DBusClient object.
2490 * @param signalName name of the signal to register
2491 * @param callback callback to call
2493 template < typename SignalType >
2494 void addSignal(std::string signalName, std::function< SignalType > callback)
2496 detail::CallId callId;
2497 detail::displayDebugCallInfoSignal(callId, signalName, info, connectionInfo->interfaceName);
2498 DBUS_W->eldbus_proxy_signal_handler_add_impl(connectionState->proxy, signalName,
2499 [callId, callback, signalName](const DBusWrapper::MessagePtr& msg) -> void {
2500 std::string errname, aux;
2501 if (DBUS_W->eldbus_message_error_get_impl(msg, errname, aux))
2503 DBUS_DEBUG("call %d: Eldbus error: %s %s", callId.id, errname.c_str(), aux.c_str());
2506 DBUS_DEBUG("call %d: received signal with signature '%s'", callId.id, DBUS_W->eldbus_message_signature_get_impl(msg).c_str());
2507 using ParamsType = typename detail::dbus_interface_traits< SignalType >::VEArgs;
2508 auto params = detail::unpackValues< ParamsType >(callId, msg);
2511 DBUS_DEBUG("call %d: failed: %s", callId.id, params.getError().message.c_str());
2516 detail::apply(callback, params.getValues());
2520 DBUS_DEBUG("unhandled exception");
2527 std::unique_ptr<detail::ConnectionState> connectionState{ new detail::ConnectionState };
2529 std::shared_ptr< ConnectionInfo > connectionInfo;
2531 static bool getFromEinaValue(const _Eina_Value* v, void* dst);
2535 * @brief Helper class describing DBUS's server interface
2538 class DBusInterfaceDescription
2540 friend class DBusServer;
2543 using MethodInfo = DBusWrapper::MethodInfo;
2544 using SignalInfo = DBusWrapper::SignalInfo;
2545 using PropertyInfo = DBusWrapper::PropertyInfo;
2546 using SignalId = DBusWrapper::SignalId;
2549 * @brief Creates empty interface description with given name
2551 * @param interfaceName name of the interface
2553 DBusInterfaceDescription(std::string interfaceName);
2556 * @brief adds new, synchronous method to the interface
2558 * When method memberName is called on DBUS, callback functor will be called
2559 * with values received from DBUS. callback won't be called, if method was
2560 * called with invalid signature. Value returned from functor (or error message)
2561 * will be marshalled back to the caller.
2563 * Template type T defines both arguments sent to the method
2564 * and expected values. Receiving different values will be reported as
2565 * error. For example:
2566 * \code{.cpp} Method<int(float, float)> \endcode
2567 * defines method, which takes two arguments (two floats) and return
2568 * single value of type int.
2570 * @param memberName name of the method
2571 * @param callback functor, which will be called
2573 template < typename T >
2574 void addMethod(const std::string& memberName, typename detail::dbus_interface_traits< T >::SyncCB callback)
2576 detail::CallId callId;
2578 methods.push_back(std::move(mi));
2579 auto& z = methods.back();
2580 z.in = detail::EldbusArgGenerator_Args< T >::get();
2581 z.out = detail::EldbusArgGenerator_ReturnType< T >::get();
2582 z.memberName = memberName;
2583 DBUS_DEBUG("call %d: method %s, in %s, out %s", callId.id, memberName.c_str(),
2584 detail::EldbusArgGenerator_Args< T >::name().c_str(),
2585 detail::EldbusArgGenerator_ReturnType< T >::name().c_str());
2586 z.callback = construct< T >(callId, callback);
2591 * @brief adds new, synchronous property to the interface
2593 * When property memberName is called on DBUS, respective callback functor will be called
2594 * with values received from DBUS. callback won't be called, if method was
2595 * called with invalid signature. Value returned from functor (or error message)
2596 * will be marshalled back to the caller.
2598 * Template type T defines type of the value hidden under property.
2599 * Note, that library automatically wraps both sent and received value into
2600 * DBUS's wrapper type.
2602 * @param memberName name of the method
2603 * @param getter functor, which will be called when property is being read
2604 * @param setter functor, which will be called when property is being set
2606 template < typename T >
2607 void addProperty(const std::string& memberName, std::function< ValueOrError< T >() > getter, std::function< ValueOrError< void >(T) > setter)
2609 properties.push_back({});
2610 auto& z = properties.back();
2611 z.memberName = memberName;
2612 z.typeSignature = detail::signature< T >::sig();
2615 detail::CallId getterId;
2616 z.getterId = getterId;
2617 DBUS_DEBUG("call %d: property %s (get) type %s", getterId.id, memberName.c_str(), detail::signature< T >::name().c_str());
2618 z.getCallback = [=](const DBusWrapper::MessagePtr& src, const DBusWrapper::MessageIterPtr& dst) -> std::string {
2621 auto v = detail::apply(getter, std::tuple<>{});
2624 detail::signature< T >::set(dst, std::get< 0 >(v.getValues()));
2625 DBUS_DEBUG("call %d: success", getterId.id);
2628 DBUS_DEBUG("call %d: failed: %s", getterId.id, v.getError().message.c_str());
2629 return v.getError().message;
2631 catch (std::exception & e)
2633 return std::string("unhandled exception (") + e.what() + ")";
2637 return "unhandled exception";
2643 detail::CallId setterId;
2644 z.setterId = setterId;
2645 DBUS_DEBUG("call %d: property %s (set) type %s", setterId.id, memberName.c_str(), detail::signature< T >::name().c_str());
2646 z.setCallback = [=](const DBusWrapper::MessagePtr& src, const DBusWrapper::MessageIterPtr& src_iter) -> std::string {
2647 std::tuple< T > value;
2648 auto src_signature = DBUS_W->eldbus_message_iter_signature_get_impl(src_iter);
2649 if (detail::signature< T >::get(src_iter, std::get< 0 >(value)))
2653 auto v = detail::apply(setter, std::move(value));
2656 DBUS_DEBUG("call %d: success", setterId.id);
2659 DBUS_DEBUG("call %d: failed: %s", setterId.id, v.getError().message.c_str());
2660 return v.getError().message;
2662 catch (std::exception & e)
2664 return std::string("unhandled exception (") + e.what() + ")";
2668 return "unhandled exception";
2671 DBUS_DEBUG("call %d: failed to unpack values, got signature '%s', expected '%s'", setterId.id,
2672 src_signature.c_str(), detail::signature< T >::sig().c_str());
2673 return "call " + std::to_string(setterId.id) + ": failed to unpack values, got signature '" +
2674 src_signature + "', expected '" + detail::signature< T >::sig() + "'";
2680 * @brief adds new signal to the interface
2682 * Template types ARGS defines values, which will be emited with the signal
2684 * @param memberName name of the method
2686 template < typename... ARGS >
2687 SignalId addSignal(const std::string& memberName)
2689 detail::CallId callId;
2690 signals.push_back({});
2691 auto& z = signals.back();
2692 z.memberName = memberName;
2693 z.args = detail::EldbusArgGenerator_Args< void(ARGS...) >::get(DBUS_W->Strings);
2695 DBUS_DEBUG("call %d: signal %s", callId.id, memberName.c_str());
2696 return SignalId{ callId };
2700 std::vector< MethodInfo > methods;
2701 std::vector< PropertyInfo > properties;
2702 std::vector< SignalInfo > signals;
2703 std::string interfaceName;
2705 template < typename T >
2706 std::function< DBusWrapper::MessagePtr(const DBusWrapper::MessagePtr & msg) > construct(detail::CallId callId,
2707 typename detail::dbus_interface_traits< T >::SyncCB callback)
2709 using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs;
2710 return [=](const DBusWrapper::MessagePtr& msg) -> DBusWrapper::MessagePtr {
2711 DBUS_DEBUG("call %d: entering", callId.id);
2712 DBusWrapper::MessagePtr ret = {};
2713 auto args = detail::unpackValues< VEArgs >(callId, msg);
2718 auto v = detail::apply(callback, std::move(args.getValues()));
2721 DBUS_DEBUG("call %d: success", callId.id);
2722 ret = DBUS_W->eldbus_message_method_return_new_impl(msg);
2723 detail::packValues(callId, ret, v);
2727 DBUS_DEBUG("call %d: failed: %s", callId.id, v.getError().message.c_str());
2728 ret = DBUS_W->eldbus_message_error_new_impl(msg, "org.freedesktop.DBus.Error.Failed", v.getError().message);
2731 catch (std::exception & e)
2733 auto txt = std::string("unhandled exception (") + e.what() + ")";
2734 DBUS_DEBUG("call %d: failed: %s", callId.id, txt.c_str());
2735 ret = DBUS_W->eldbus_message_error_new_impl(msg, "org.freedesktop.DBus.Error.Failed", txt);
2739 DBUS_DEBUG("call %d: failed: %s", callId.id, "unhandled exception");
2740 ret = DBUS_W->eldbus_message_error_new_impl(msg, "org.freedesktop.DBus.Error.Failed", "unhandled exception");
2745 std::ostringstream err;
2746 err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << DBUS_W->eldbus_message_signature_get_impl(msg) << "'";
2747 auto str = err.str();
2748 DBUS_DEBUG("call %d: failed: %s", callId.id, str.c_str());
2749 ret = DBUS_W->eldbus_message_error_new_impl(msg, "org.freedesktop.DBus.Error.InvalidArgs", str);
2757 * @brief Class representing server's end of DBUS connection
2759 * Allows listening (synchronously and asynchronosly) on methods on selected interface
2760 * Allows listening (synchronously and asynchronosly) on setting / getting properties.
2761 * Allows emiting signals.
2767 * @brief Constructs non-connected dbus server.
2769 DBusServer() = default;
2772 * @brief Constructs dbus server on either system or user dbus connection.
2774 DBusServer(ConnectionType tp);
2777 * @brief Constructs dbus server on connection from getDBusConnectionByType
2779 DBusServer(const DBusWrapper::ConnectionPtr& conn);
2784 * Destructor will properly destroy everything. Destructor will cancel
2787 ~DBusServer() = default;
2789 DBusServer(const DBusServer&) = delete;
2790 DBusServer(DBusServer&&) = default;
2792 DBusServer& operator=(DBusServer&&) = default;
2793 DBusServer& operator=(const DBusServer&) = delete;
2796 * @brief Registers interface on given path name
2798 * @param pathName path object to register interface on.
2802 void addInterface(const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback = false);
2805 * @brief Gets bus name of the current connection (must be connected)
2807 std::string getBusName() const;
2810 * @brief Returns connection object for this dbus server object
2812 * @return connection object
2814 DBusWrapper::ConnectionPtr getConnection();
2817 * @brief Emits signal
2819 * Emits signal based only on data passed to the function
2821 * @param signal identifier of the signal
2822 * @param args values to emit
2824 template < typename... ARGS >
2825 void emit2(const std::string& path, const std::string& interfaceName,
2826 const std::string& signalName, const ARGS&... args)
2828 auto msg = DBUS_W->eldbus_message_signal_new_impl(path, interfaceName, signalName);
2830 detail::packValues(id, msg, args...);
2831 DBUS_W->eldbus_connection_send_impl(connection, msg);
2835 * @brief Returns current object path, when handling call to property / method
2837 * User can call this function from inside callback used to handle property / method calls.
2838 * It will retrieve object's path used in the call. Note, that in asynchronous handling
2839 * of those calls user need to retrieve and store the current object / current connection
2840 * as the value will change at the moment user's callback handling will exit. For example:
2842 * DBusInterfaceDescription interface{"name"};
2843 * auto handler_later = [](std::function<void(void)> done_cb) {
2844 * // process something later on
2845 * DBusServer::getCurrentObjectPath(); // this will return empty string
2847 * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
2848 * DBusServer::getCurrentObjectPath(); // this will current object's path
2850 * // do some processing later on and call done_cb, when it's done
2851 * register_to_call_sometime_later_on(std::move(done_cb));
2855 static std::string getCurrentObjectPath() { return currentObjectPath; }
2858 * @brief Returns current connection object, when handling call to property / method
2860 * User can call this function from inside callback used to handle property / method calls.
2861 * It will retrieve object's path used in the call. Note, that in asynchronous handling
2862 * of those calls user need to retrieve and store the current object / current connection
2863 * as the value will change at the moment user's callback handling will exit. For example:
2865 * DBusInterfaceDescription interface{"name"};
2866 * auto handler_later = [](std::function<void(void)> done_cb) {
2867 * // process something later on
2868 * DBusServer::getCurrentObjectPath(); // this will return empty string
2870 * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
2871 * DBusServer::getCurrentObjectPath(); // this will current object's path
2873 * // do some processing later on and call done_cb, when it's done
2874 * register_to_call_sometime_later_on(std::move(done_cb));
2878 static const DBusWrapper::ConnectionPtr& getCurrentConnection() { return currentConnection; }
2881 class CurrentObjectSetter
2884 CurrentObjectSetter(DBusWrapper::ConnectionPtr con, std::string path)
2886 currentObjectPath = std::move(path);
2887 currentConnection = std::move(con);
2889 ~CurrentObjectSetter()
2891 currentObjectPath = "";
2892 currentConnection = {};
2894 CurrentObjectSetter(const CurrentObjectSetter&) = delete;
2895 CurrentObjectSetter(CurrentObjectSetter&&) = delete;
2896 void operator=(const CurrentObjectSetter&) = delete;
2897 void operator=(CurrentObjectSetter&&) = delete;
2901 DBusWrapper::ConnectionPtr connection;
2902 struct DestructorObject {
2903 std::vector<std::function<void()>> destructors;
2904 ~DestructorObject() {
2905 for (auto& a : destructors) a();
2909 std::unique_ptr<DestructorObject> destructorObject{ new DestructorObject() };
2910 static thread_local std::string currentObjectPath;
2911 static thread_local DBusWrapper::ConnectionPtr currentConnection;
2915 DBusWrapper::ConnectionPtr getDBusConnectionByType(ConnectionType tp);
2916 DBusWrapper::ConnectionPtr getDBusConnectionByName(const std::string& name);
2917 std::string getConnectionName(const DBusWrapper::ConnectionPtr&);
2922 template < size_t INDEX, typename... ARGS >
2923 inline auto get(DBus::ValueOrError< ARGS... >& v) -> decltype(std::get< INDEX >(v.getValues()))&
2925 return std::get< INDEX >(v.getValues());
2928 template < size_t INDEX, typename... ARGS >
2929 inline auto get(const DBus::ValueOrError< ARGS... >& v) -> decltype(std::get< INDEX >(v.getValues()))
2931 return std::get< INDEX >(v.getValues());
2935 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H