Use existing callback ID for recurring callbacks
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / tizen-wayland / atspi / dbus.h
1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
3
4 /*
5  * Copyright 2020  Samsung Electronics Co., Ltd
6  *
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
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12
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.
18  */
19
20  // EXTERNAL INCLUDES
21 #include <memory>
22 #include <array>
23 #include <atomic>
24 #include <cstdint>
25 #include <map>
26 #include <sstream>
27 #include <string>
28 #include <thread>
29 #include <tuple>
30 #include <type_traits>
31 #include <unordered_map>
32 #include <vector>
33 #include <functional>
34 #include <string.h>
35
36 // INTERNAL INCLUDES
37 #include <dali/devel-api/adaptor-framework/atspi-accessibility.h>
38 #include <dali/internal/accessibility/tizen-wayland/atspi/accessibility-optional.h>
39
40 #define ATSPI_PREFIX_PATH "/org/a11y/atspi/accessible/"
41 #define ATSPI_NULL_PATH "/org/a11y/atspi/null"
42
43 struct _Eina_Value;
44
45 struct ObjectPath
46 {
47   std::string value;
48 };
49
50 struct DALI_ADAPTOR_API DBusWrapper
51 {
52   virtual ~DBusWrapper() = default;
53
54   enum class ConnectionType
55   {
56     SYSTEM,
57     SESSION
58   };
59
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>; \
64
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, )
72
73 #undef DEFINE_TYPE
74     virtual ConnectionPtr eldbus_address_connection_get_impl(const std::string& addr) = 0;
75
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)
81
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)
93
94 #undef eldbus_message_iter_arguments_append_impl_basic
95 #undef eldbus_message_iter_arguments_append_impl_basic_impl
96
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;
104
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;
120
121   class StringStorage
122   {
123   public:
124     struct char_ptr_deleter
125     {
126       void operator()(char* p)
127       {
128         free(p);
129       }
130     };
131     std::vector< std::unique_ptr< char, char_ptr_deleter > > storage;
132
133     const char* add(const char* txt)
134     {
135       auto ptr = strdup(txt);
136       storage.push_back(std::unique_ptr< char, char_ptr_deleter >(ptr));
137       return storage.back().get();
138     }
139     const char* add(const std::string& txt)
140     {
141       return add(txt.c_str());
142     }
143   };
144
145   struct CallId
146   {
147     static std::atomic< unsigned int > LastId;
148     unsigned int id = ++LastId;
149   };
150   struct MethodInfo
151   {
152     CallId id;
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;
156   };
157   struct SignalInfo
158   {
159     CallId id;
160     std::string memberName;
161     std::vector< std::pair<std::string, std::string> > args;
162     unsigned int uniqueId;
163   };
164   struct PropertyInfo
165   {
166     CallId setterId, getterId;
167     std::string memberName, typeSignature;
168     std::function< std::string(const DBusWrapper::MessagePtr & src, const DBusWrapper::MessageIterPtr & dst) > getCallback, setCallback;
169   };
170   struct SignalId
171   {
172     CallId id;
173
174     SignalId() = default;
175     SignalId(CallId id) : id(id) {}
176   };
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>);
187
188   StringStorage Strings;
189 };
190
191 namespace detail {
192   enum class MethodType {
193     Method, Getter, Setter
194   };
195 }
196
197 namespace std {
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));
203       size_t v = a1;
204       v = (v * 11400714819323198485llu) + a2;
205       v = (v * 11400714819323198485llu) + a3;
206       return v;
207     }
208   };
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));
215       size_t v = a1;
216       v = (v * 11400714819323198485llu) + a2;
217       v = (v * 11400714819323198485llu) + a3;
218       v = (v * 11400714819323198485llu) + a4;
219       return v;
220     }
221   };
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);
227       size_t v = a1;
228       v = (v * 11400714819323198485llu) + a2;
229       v = (v * 11400714819323198485llu) + a3;
230       return v;
231     }
232   };
233 }
234
235 namespace detail {
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 };
240   };
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 };
244   };
245   template <typename T, typename = void> struct Encoder;
246   template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple;
247 }
248
249 namespace detail {
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 }; };
261 }
262
263
264 #define DBUS_DEBUG( ... )                                \
265   do                                                     \
266   {                                                      \
267     DBus::debugPrint( __FILE__, __LINE__, __VA_ARGS__ ); \
268   } while( 0 )
269
270 #define DBUS_W DBusWrapper::Installed()
271
272 /**
273  * @brief Template based, single file, wrapper library around eldbus for DBUS based communication.
274  *
275  * Main motivation was missing asynchronous calls in AT-SPI library and difficulties,
276  * when using eldbus from C++.
277  *
278  * The library:
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
285  *   what's going on
286  *
287  * DBUS's method signatures (and expected return values) are specified as template argument,
288  * using functor syntax. For example:
289  * \code{.cpp}
290  * auto dbus = DBusClient{ ... };
291  * auto v = dbus.method<std::tuple<int, float>(float, float, std::string)>("foo").call(1.0f, 2.0f, "qwe");
292  * \endcode
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:
298  * \code{.cpp}
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");
302  * \endcode
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.
307  *
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.
310  */
311 namespace DBus
312 {
313
314   class DBusServer;
315   class DBusClient;
316   class DBusInterfaceDescription;
317
318   /**
319    * @brief Formats debug message and calls debug printer (if any) with it
320    */
321   void debugPrint(const char* file, size_t line, const char* format, ...);
322
323   /**
324    * @brief Sets debug printer callback, which will be called with debug messages
325    *
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.
329    */
330   void setDebugPrinter(std::function< void(const char*, size_t) >);
331
332   struct Error
333   {
334     std::string message;
335
336     Error() = default;
337     Error(std::string msg) : message(std::move(msg))
338     {
339       assert(!message.empty());
340     }
341   };
342
343   struct Success
344   {
345   };
346
347
348   /**
349    * @brief Value representing data, that came from DBUS or error message
350    *
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:
355    * \code{.cpp}
356    * ValueOrError<> v1;
357    * ValueOrError<void> v2;
358    * \endcode
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.
361    */
362   template < typename... ARGS >
363   class ValueOrError
364   {
365   public:
366     /**
367      * @brief Empty constructor. Valid only, if all ARGS types are default constructible.
368      */
369     ValueOrError() = default;
370
371     /**
372      * @brief Value constructor.
373      *
374      * This will be initialized as success with passed in values.
375      */
376     ValueOrError(ARGS... t) : value(std::move(t)...) {}
377
378     /**
379      * @brief Alternative Value constructor.
380      *
381      * This will be initialized as success with passed in values.
382      */
383     ValueOrError(std::tuple< ARGS... > t) : value(std::move(t)) {}
384
385     /**
386      * @brief Error constructor. This will be initialized as failure with given error message.
387      */
388     ValueOrError(Error e) : error(std::move(e))
389     {
390       assert(!error.message.empty());
391     }
392
393     /**
394      * @brief bool operator.
395      *
396      * Returns true, if operation was successful (getValues member is callable), or false
397      * when operation failed (getError is callable).
398      */
399     explicit operator bool() const
400     {
401       return error.message.empty();
402     }
403
404     /**
405      * @brief Returns error message object.
406      *
407      * Returns object containing error message associated with the failed operation.
408      * Only callable, if operation actually failed, otherwise will assert.
409      */
410     const Error& getError() const
411     {
412       return error;
413     }
414
415     /**
416      * @brief Returns modifiable tuple of held data.
417      *
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.
421      */
422     std::tuple< ARGS... >& getValues()
423     {
424       assert(*this);
425       return value;
426     }
427
428     /**
429      * @brief Returns const tuple of held data.
430      *
431      * Returns const reference to the internal tuple containing held data.
432      * Only callable, if operation actually successed, otherwise will assert.
433      */
434     const std::tuple< ARGS... >& getValues() const
435     {
436       assert(*this);
437       return value;
438     }
439
440   protected:
441     std::tuple< ARGS... > value;
442     Error error;
443
444   };
445
446
447   template <>
448   class ValueOrError<>
449   {
450   public:
451     ValueOrError() = default;
452     ValueOrError(std::tuple<> t) {}
453     ValueOrError(Error e) : error(std::move(e))
454     {
455       assert(!error.message.empty());
456     }
457
458     explicit operator bool() const
459     {
460       return error.message.empty();
461     }
462     const Error& getError() const
463     {
464       return error;
465     }
466     std::tuple<>& getValues()
467     {
468       assert(*this);
469       static std::tuple<> t;
470       return t;
471     }
472     std::tuple<> getValues() const
473     {
474       assert(*this);
475       return {};
476     }
477
478   protected:
479     Error error;
480   };
481
482   template <>
483   class ValueOrError< void >
484   {
485   public:
486     ValueOrError() = default;
487     ValueOrError(Success) {}
488     ValueOrError(Error e) : error(std::move(e))
489     {
490       assert(!error.message.empty());
491     }
492
493     explicit operator bool() const
494     {
495       return error.message.empty();
496     }
497     const Error& getError() const
498     {
499       return error;
500     }
501     std::tuple<>& getValues()
502     {
503       assert(*this);
504       static std::tuple<> t;
505       return t;
506     }
507     std::tuple<> getValues() const
508     {
509       assert(*this);
510       return {};
511     }
512
513   protected:
514     Error error;
515   };
516
517   using ObjectPath = ObjectPath;
518
519
520   /**
521    * @brief Class used to marshall DBUS's variant type
522    *
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.
528    */
529   template < typename A >
530   struct EldbusVariant
531   {
532     A value;
533   };
534
535   /**
536    * @brief Namespace for private, internal functions and classes
537    */
538   namespace detail
539   {
540     template < typename T, typename = void >
541     struct signature;
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 > >;
554
555     /**
556      * @brief Signature class for marshalling uint8 type.
557      */
558     template <>
559     struct signature< uint8_t >
560     {
561       /**
562        * @brief Returns name of type marshalled, for informative purposes
563        */
564       static std::string name()
565       {
566         return "uint8_t";
567       }
568
569       /**
570        * @brief Returns DBUS' signature of type marshalled
571        */
572       static std::string sig()
573       {
574         return "y";
575       }
576
577       /**
578        * @brief Marshals value v as marshalled type into message
579        */
580       static void set(const DBusWrapper::MessageIterPtr& iter, uint8_t v)
581       {
582         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
583       }
584
585       /**
586        * @brief Marshals value from marshalled type into variable v
587        */
588       static bool get(const DBusWrapper::MessageIterPtr& iter, uint8_t& v)
589       {
590         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
591       }
592     };
593
594     /**
595      * @brief Signature class for marshalling uint16 type.
596      */
597     template <>
598     struct signature< uint16_t >
599     {
600       /**
601        * @brief Returns name of type marshalled, for informative purposes
602        */
603       static std::string name()
604       {
605         return "uint16_t";
606       }
607
608       /**
609        * @brief Returns DBUS' signature of type marshalled
610        */
611       static std::string sig()
612       {
613         return "q";
614       }
615
616       /**
617        * @brief Marshals value v as marshalled type into message
618        */
619       static void set(const DBusWrapper::MessageIterPtr& iter, uint16_t v)
620       {
621         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
622       }
623
624       /**
625        * @brief Marshals value from marshalled type into variable v
626        */
627       static bool get(const DBusWrapper::MessageIterPtr& iter, uint16_t& v)
628       {
629         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
630       }
631     };
632
633     /**
634      * @brief Signature class for marshalling uint32 type.
635      */
636     template <>
637     struct signature< uint32_t >
638     {
639       /**
640        * @brief Returns name of type marshalled, for informative purposes
641        */
642       static std::string name()
643       {
644         return "uint32_t";
645       }
646
647       /**
648        * @brief Returns DBUS' signature of type marshalled
649        */
650       static std::string sig()
651       {
652         return "u";
653       }
654
655       /**
656        * @brief Marshals value v as marshalled type into message
657        */
658       static void set(const DBusWrapper::MessageIterPtr& iter, uint32_t v)
659       {
660         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
661       }
662
663       /**
664        * @brief Marshals value from marshalled type into variable v
665        */
666       static bool get(const DBusWrapper::MessageIterPtr& iter, uint32_t& v)
667       {
668         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
669       }
670     };
671
672     /**
673      * @brief Signature class for marshalling uint64 type.
674      */
675     template <>
676     struct signature< uint64_t >
677     {
678       /**
679        * @brief Returns name of type marshalled, for informative purposes
680        */
681       static std::string name()
682       {
683         return "uint64_t";
684       }
685
686       /**
687        * @brief Returns DBUS' signature of type marshalled
688        */
689       static std::string sig()
690       {
691         return "t";
692       }
693
694       /**
695        * @brief Marshals value v as marshalled type into message
696        */
697       static void set(const DBusWrapper::MessageIterPtr& iter, uint64_t v)
698       {
699         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
700       }
701
702       /**
703        * @brief Marshals value from marshalled type into variable v
704        */
705       static bool get(const DBusWrapper::MessageIterPtr& iter, uint64_t& v)
706       {
707         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
708       }
709     };
710
711     /**
712      * @brief Signature class for marshalling int16 type.
713      */
714     template <>
715     struct signature< int16_t >
716     {
717       /**
718        * @brief Returns name of type marshalled, for informative purposes
719        */
720       static std::string name()
721       {
722         return "int16_t";
723       }
724
725       /**
726        * @brief Returns DBUS' signature of type marshalled
727        */
728       static std::string sig()
729       {
730         return "n";
731       }
732
733       /**
734        * @brief Marshals value v as marshalled type into message
735        */
736       static void set(const DBusWrapper::MessageIterPtr& iter, int16_t v)
737       {
738         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
739       }
740
741       /**
742        * @brief Marshals value from marshalled type into variable v
743        */
744       static bool get(const DBusWrapper::MessageIterPtr& iter, int16_t& v)
745       {
746         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
747       }
748     };
749
750     /**
751      * @brief Signature class for marshalling int32 type.
752      */
753     template <>
754     struct signature< int32_t >
755     {
756       /**
757        * @brief Returns name of type marshalled, for informative purposes
758        */
759       static std::string name()
760       {
761         return "int32_t";
762       }
763
764       /**
765        * @brief Returns DBUS' signature of type marshalled
766        */
767       static std::string sig()
768       {
769         return "i";
770       }
771
772       /**
773        * @brief Marshals value v as marshalled type into message
774        */
775       static void set(const DBusWrapper::MessageIterPtr& iter, int32_t v)
776       {
777         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
778       }
779
780       /**
781        * @brief Marshals value from marshalled type into variable v
782        */
783       static bool get(const DBusWrapper::MessageIterPtr& iter, int32_t& v)
784       {
785         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
786       }
787     };
788
789     /**
790      * @brief Signature class for marshalling int64 type.
791      */
792     template <>
793     struct signature< int64_t >
794     {
795       /**
796        * @brief Returns name of type marshalled, for informative purposes
797        */
798       static std::string name()
799       {
800         return "int64_t";
801       }
802
803       /**
804        * @brief Returns DBUS' signature of type marshalled
805        */
806       static std::string sig()
807       {
808         return "x";
809       }
810
811       /**
812        * @brief Marshals value v as marshalled type into message
813        */
814       static void set(const DBusWrapper::MessageIterPtr& iter, int64_t v)
815       {
816         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
817       }
818
819       /**
820        * @brief Marshals value from marshalled type into variable v
821        */
822       static bool get(const DBusWrapper::MessageIterPtr& iter, int64_t& v)
823       {
824         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
825       }
826     };
827
828     /**
829      * @brief Signature class for marshalling double type.
830      */
831     template <>
832     struct signature< double >
833     {
834       /**
835        * @brief Returns name of type marshalled, for informative purposes
836        */
837       static std::string name()
838       {
839         return "double";
840       }
841
842       /**
843        * @brief Returns DBUS' signature of type marshalled
844        */
845       static std::string sig()
846       {
847         return "d";
848       }
849
850       /**
851        * @brief Marshals value v as marshalled type into message
852        */
853       static void set(const DBusWrapper::MessageIterPtr& iter, double v)
854       {
855         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
856       }
857
858       /**
859        * @brief Marshals value from marshalled type into variable v
860        */
861       static bool get(const DBusWrapper::MessageIterPtr& iter, double& v)
862       {
863         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
864       }
865
866       /**
867        * @brief Marshals value from marshalled type into variable v
868        */
869       static bool get(const DBusWrapper::MessageIterPtr& iter, float& v2)
870       {
871         double v = 0;
872         auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
873         v2 = static_cast<float>(v);
874         return r;
875       }
876     };
877
878     /**
879      * @brief Signature class for marshalling float type.
880      */
881     template <>
882     struct signature< float >
883     {
884       /**
885        * @brief Returns name of type marshalled, for informative purposes
886        */
887       static std::string name()
888       {
889         return "float";
890       }
891
892       /**
893        * @brief Returns DBUS' signature of type marshalled
894        */
895       static std::string sig()
896       {
897         return "d";
898       }
899
900       /**
901        * @brief Marshals value v as marshalled type into message
902        */
903       static void set(const DBusWrapper::MessageIterPtr& iter, float v)
904       {
905         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
906       }
907
908       /**
909        * @brief Marshals value from marshalled type into variable v
910        */
911       static bool get(const DBusWrapper::MessageIterPtr& iter, double& v)
912       {
913         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
914       }
915
916       /**
917        * @brief Marshals value from marshalled type into variable v
918        */
919       static bool get(const DBusWrapper::MessageIterPtr& iter, float& v2)
920       {
921         double v = 0;
922         auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
923         v2 = static_cast<float>(v);
924         return r;
925       }
926     };
927
928     /**
929      * @brief Signature class for marshalling boolean type.
930      */
931     template <>
932     struct signature< bool >
933     {
934       /**
935        * @brief Returns name of type marshalled, for informative purposes
936        */
937       static std::string name()
938       {
939         return "bool";
940       }
941
942       /**
943        * @brief Returns DBUS' signature of type marshalled
944        */
945       static std::string sig()
946       {
947         return "b";
948       }
949
950       /**
951        * @brief Marshals value v as marshalled type into message
952        */
953       static void set(const DBusWrapper::MessageIterPtr& iter, bool v)
954       {
955         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
956       }
957
958       /**
959        * @brief Marshals value from marshalled type into variable v
960        */
961       static bool get(const DBusWrapper::MessageIterPtr& iter, bool& v)
962       {
963         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
964       }
965     };
966
967     template < typename T >
968     struct signature< T, typename std::enable_if< std::is_enum< T >::value, void >::type >
969     {
970       /**
971        * @brief Returns name of type marshalled, for informative purposes
972        */
973       static std::string name()
974       {
975         return "enum";
976       }
977
978       /**
979        * @brief Returns DBUS' signature of type marshalled
980        */
981       static std::string sig()
982       {
983         return signature<typename std::underlying_type<T>::type>::sig();
984       }
985
986       /**
987        * @brief Marshals value v as marshalled type into message
988        */
989       static void set(const DBusWrapper::MessageIterPtr& iter, T v)
990       {
991         signature<typename std::underlying_type<T>::type>::set(iter, static_cast<int64_t>(v));
992       }
993
994       /**
995        * @brief Marshals value from marshalled type into variable v
996        */
997       static bool get(const DBusWrapper::MessageIterPtr& iter, T& v)
998       {
999         typename std::underlying_type<T>::type q = 0;
1000         if (!signature<typename std::underlying_type<T>::type>::get(iter, q))
1001           return false;
1002
1003         v = static_cast<T>(q);
1004         return true;
1005       }
1006     };
1007
1008     /**
1009      * @brief Signature class for marshalling string type.
1010      *
1011      * Both (const) char * and std::string types are accepted as value to send.
1012      * Only std::string is accepted as value to receive.
1013      */
1014     template <>
1015     struct signature< std::string >
1016     {
1017       /**
1018        * @brief Returns name of type marshalled, for informative purposes
1019        */
1020       static std::string name()
1021       {
1022         return "string";
1023       }
1024
1025       /**
1026        * @brief Returns DBUS' signature of type marshalled
1027        */
1028       static std::string sig()
1029       {
1030         return "s";
1031       }
1032
1033       /**
1034        * @brief Marshals value v as marshalled type into message
1035        */
1036       static void set(const DBusWrapper::MessageIterPtr& iter, const std::string& v)
1037       {
1038         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1039       }
1040
1041       /**
1042        * @brief Marshals value from marshalled type into variable v
1043        */
1044       static bool get(const DBusWrapper::MessageIterPtr& iter, std::string& v)
1045       {
1046         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1047       }
1048     };
1049
1050     template <>
1051     struct signature< ObjectPath >
1052     {
1053       /**
1054        * @brief Returns name of type marshalled, for informative purposes
1055        */
1056       static std::string name()
1057       {
1058         return "path";
1059       }
1060
1061       /**
1062        * @brief Returns DBUS' signature of type marshalled
1063        */
1064       static std::string sig()
1065       {
1066         return "o";
1067       }
1068
1069       /**
1070        * @brief Marshals value v as marshalled type into message
1071        */
1072       static void set(const DBusWrapper::MessageIterPtr& iter, const std::string& v)
1073       {
1074         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1075       }
1076
1077       /**
1078        * @brief Marshals value v as marshalled type into message
1079        */
1080       static void set(const DBusWrapper::MessageIterPtr& iter, const ObjectPath& v)
1081       {
1082         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1083       }
1084
1085       /**
1086        * @brief Marshals value v as marshalled type into message
1087        */
1088       static void set(const DBusWrapper::MessageIterPtr& iter, const char* v)
1089       {
1090         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1091       }
1092
1093       /**
1094        * @brief Marshals value from marshalled type into variable v
1095        */
1096       static bool get(const DBusWrapper::MessageIterPtr& iter, ObjectPath& v)
1097       {
1098         return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1099       }
1100
1101       /**
1102        * @brief Marshals value from marshalled type into variable v
1103        */
1104       static bool get(const DBusWrapper::MessageIterPtr& iter, std::string& v)
1105       {
1106         ObjectPath q;
1107         if (!DBUS_W->eldbus_message_iter_get_and_next_impl(iter, q)) return false;
1108         v = std::move(q.value);
1109         return true;
1110       }
1111     };
1112
1113     /**
1114      * @brief Signature class for marshalling (const) char * type.
1115      *
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.
1118      */
1119     template <>
1120     struct signature< char* >
1121     {
1122       /**
1123        * @brief Returns name of type marshalled, for informative purposes
1124        */
1125       static std::string name()
1126       {
1127         return "string";
1128       }
1129
1130       /**
1131        * @brief Returns DBUS' signature of type marshalled
1132        */
1133       static std::string sig()
1134       {
1135         return "s";
1136       }
1137
1138       /**
1139        * @brief Marshals value v as marshalled type into message
1140        */
1141       static void set(const DBusWrapper::MessageIterPtr& iter, const std::string& v)
1142       {
1143         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1144       }
1145
1146       /**
1147        * @brief Marshals value v as marshalled type into message
1148        */
1149       static void set(const DBusWrapper::MessageIterPtr& iter, const char* v)
1150       {
1151         DBUS_W->eldbus_message_iter_arguments_append_impl(iter, std::string{ v });
1152       }
1153     };
1154
1155     template < size_t INDEX, typename A, typename... ARGS >
1156     struct signature_tuple_element_type_helper
1157     {
1158       using type = typename signature_tuple_element_type_helper< INDEX - 1, ARGS... >::type;
1159     };
1160
1161     template < typename A, typename... ARGS >
1162     struct signature_tuple_element_type_helper< 0, A, ARGS... >
1163     {
1164       using type = A;
1165     };
1166
1167     /**
1168      * @brief Helper class to marshall tuples
1169      *
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.
1173      */
1174     template < size_t INDEX, size_t SIZE, typename... ARGS >
1175     struct signature_tuple_helper
1176     {
1177       using current_type = typename signature_tuple_element_type_helper< INDEX, ARGS... >::type;
1178
1179       /**
1180        * @brief Returns name of type marshalled, for informative purposes
1181        */
1182       static std::string name()
1183       {
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();
1187       }
1188
1189       /**
1190        * @brief Returns DBUS' signature of type marshalled
1191        */
1192       static std::string sig()
1193       {
1194         return signature< current_type >::sig() + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::sig();
1195       }
1196
1197       /**
1198        * @brief Marshals value v as marshalled type into message
1199        */
1200       static void set(const DBusWrapper::MessageIterPtr& iter, const std::tuple< ARGS... >& args)
1201       {
1202         signature< current_type >::set(iter, std::get< INDEX >(args));
1203         signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::set(iter, args);
1204       }
1205
1206       /**
1207        * @brief Marshals value from marshalled type into variable v
1208        */
1209       static bool get(const DBusWrapper::MessageIterPtr& iter, std::tuple< ARGS... >& args)
1210       {
1211         return signature< current_type >::get(iter, std::get< INDEX >(args)) &&
1212           signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::get(iter, args);
1213       }
1214     };
1215
1216     /**
1217      * @brief Helper class to marshall tuples
1218      *
1219      * This class marks end of the tuple marshalling. Members of this class are called
1220      * when INDEX value is equal to SIZE.
1221      */
1222     template < size_t SIZE, typename... ARGS >
1223     struct signature_tuple_helper< SIZE, SIZE, ARGS... >
1224     {
1225       /**
1226        * @brief Returns name of type marshalled, for informative purposes
1227        */
1228       static std::string name()
1229       {
1230         return "";
1231       }
1232
1233       /**
1234        * @brief Returns DBUS' signature of type marshalled
1235        */
1236       static std::string sig()
1237       {
1238         return "";
1239       }
1240
1241       /**
1242        * @brief Marshals value v as marshalled type into message
1243        */
1244       static void set(const DBusWrapper::MessageIterPtr& iter, const std::tuple< ARGS... >& args)
1245       {
1246       }
1247
1248       /**
1249        * @brief Marshals value from marshalled type into variable v
1250        */
1251       static bool get(const DBusWrapper::MessageIterPtr& iter, std::tuple< ARGS... >& args)
1252       {
1253         return true;
1254       }
1255     };
1256
1257     /**
1258      * @brief Signature class for marshalling tuple of values
1259      *
1260      * This class marshalls tuple of values. This represents
1261      * DBUS struct typle, encoded with character 'r'
1262      */
1263     template < typename... ARGS >
1264     struct signature< std::tuple< ARGS... > >
1265     {
1266       /**
1267        * @brief Returns name of type marshalled, for informative purposes
1268        */
1269       static std::string name()
1270       {
1271         return "tuple<" + signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::name() + ">";
1272       }
1273
1274       /**
1275        * @brief Returns DBUS' signature of type marshalled
1276        */
1277       static std::string sig()
1278       {
1279         return "(" + signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::sig() + ")";
1280       }
1281
1282       /**
1283        * @brief Marshals value v as marshalled type into message
1284        */
1285       static void set(const DBusWrapper::MessageIterPtr& iter, const std::tuple< ARGS... >& args)
1286       {
1287         auto entry = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'r', "");
1288         signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::set(entry, args);
1289       }
1290
1291       /**
1292        * @brief Marshals value from marshalled type into variable v
1293        */
1294       static bool get(const DBusWrapper::MessageIterPtr& iter, std::tuple< ARGS... >& args)
1295       {
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);
1299       }
1300     };
1301
1302     /**
1303      * @brief Signature class for marshalling ValueOrError template type
1304      *
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
1310      * or
1311      * \code{.cpp} ValueOrError<std::tuple<std::string, std::string, std::tuple<std::string>>> \endcode
1312      */
1313     template < typename... ARGS >
1314     struct signature< ValueOrError< ARGS... > >
1315     {
1316       /**
1317        * @brief Returns name of type marshalled, for informative purposes
1318        */
1319       static std::string name()
1320       {
1321         return "ValueOrError<" + signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::name() + ">";
1322       }
1323
1324       /**
1325        * @brief Returns DBUS' signature of type marshalled
1326        */
1327       static std::string sig()
1328       {
1329         return signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::sig();
1330       }
1331
1332       /**
1333        * @brief Marshals value v as marshalled type into message
1334        */
1335       static void set(const DBusWrapper::MessageIterPtr& iter, const ValueOrError< ARGS... >& args)
1336       {
1337         signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::set(iter, args.getValues());
1338       }
1339
1340       /**
1341        * @brief Marshals value from marshalled type into variable v
1342        */
1343       static bool get(const DBusWrapper::MessageIterPtr& iter, ValueOrError< ARGS... >& args)
1344       {
1345         return signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::get(iter, args.getValues());
1346       }
1347     };
1348
1349     /**
1350      * @brief Signature class for marshalling ValueOrError<void> type
1351      */
1352     template <>
1353     struct signature< ValueOrError< void > >
1354     {
1355       /**
1356        * @brief Returns name of type marshalled, for informative purposes
1357        */
1358       static std::string name()
1359       {
1360         return "ValueOrError<void>";
1361       }
1362
1363       /**
1364        * @brief Returns DBUS' signature of type marshalled
1365        */
1366       static std::string sig()
1367       {
1368         return "";
1369       }
1370
1371       /**
1372        * @brief Marshals value v as marshalled type into message
1373        */
1374       static void set(const DBusWrapper::MessageIterPtr& iter, const ValueOrError< void >& args)
1375       {
1376       }
1377
1378       /**
1379        * @brief Marshals value from marshalled type into variable v
1380        */
1381       static bool get(const DBusWrapper::MessageIterPtr& iter, ValueOrError< void >& args)
1382       {
1383         return true;
1384       }
1385     };
1386
1387     /**
1388      * @brief Signature class for marshalling ValueOrError<> type
1389      */
1390     template <>
1391     struct signature< ValueOrError<> >
1392     {
1393       /**
1394        * @brief Returns name of type marshalled, for informative purposes
1395        */
1396       static std::string name()
1397       {
1398         return "ValueOrError<>";
1399       }
1400
1401       /**
1402        * @brief Returns DBUS' signature of type marshalled
1403        */
1404       static std::string sig()
1405       {
1406         return "";
1407       }
1408
1409       /**
1410        * @brief Marshals value v as marshalled type into message
1411        */
1412       static void set(const DBusWrapper::MessageIterPtr& iter, const ValueOrError<>& args)
1413       {
1414       }
1415
1416       /**
1417        * @brief Marshals value from marshalled type into variable v
1418        */
1419       static bool get(const DBusWrapper::MessageIterPtr& iter, ValueOrError<>& args)
1420       {
1421         return true;
1422       }
1423     };
1424
1425     /**
1426      * @brief Signature class for marshalling pair of types
1427      */
1428     template < typename A, typename B >
1429     struct signature< std::pair< A, B > >
1430     {
1431       /**
1432        * @brief Returns name of type marshalled, for informative purposes
1433        */
1434       static std::string name()
1435       {
1436         return "pair<" + signature_tuple_helper< 0, 2, A, B >::name() + ">";
1437       }
1438
1439       /**
1440        * @brief Returns DBUS' signature of type marshalled
1441        */
1442       static std::string sig()
1443       {
1444         return "(" + signature_tuple_helper< 0, 2, A, B >::sig() + ")";
1445       }
1446
1447       /**
1448        * @brief Marshals value v as marshalled type into message
1449        */
1450       static void set(const DBusWrapper::MessageIterPtr& iter, const std::pair< A, B >& ab, bool dictionary = false)
1451       {
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);
1454       }
1455
1456       /**
1457        * @brief Marshals value from marshalled type into variable v
1458        */
1459       static bool get(const DBusWrapper::MessageIterPtr& iter, std::pair< A, B >& ab)
1460       {
1461         auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'r');
1462         if (!entry) {
1463           entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, '{');
1464           if (!entry) return false;
1465         }
1466
1467         std::tuple< A, B > ab_tmp;
1468         auto z = signature_tuple_helper< 0, 2, A, B >::get(entry, ab_tmp);
1469         if (z)
1470         {
1471           ab.first = std::move(std::get< 0 >(ab_tmp));
1472           ab.second = std::move(std::get< 1 >(ab_tmp));
1473         }
1474         return z;
1475       }
1476     };
1477
1478     /**
1479      * @brief Signature class for marshalling std::vector template type
1480      *
1481      * This marshals container's content as DBUS a ascii character type code.
1482      */
1483     template < typename A >
1484     struct signature< std::vector< A > >
1485     {
1486       /**
1487        * @brief Returns name of type marshalled, for informative purposes
1488        */
1489       static std::string name()
1490       {
1491         return "vector<" + signature< A >::name() + ">";
1492       }
1493
1494       /**
1495        * @brief Returns DBUS' signature of type marshalled
1496        */
1497       static std::string sig()
1498       {
1499         return "a" + signature< A >::sig();
1500       }
1501
1502       /**
1503        * @brief Marshals value v as marshalled type into message
1504        */
1505       static void set(const DBusWrapper::MessageIterPtr& iter, const std::vector< A >& v)
1506       {
1507         auto lst = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'a', signature< A >::sig());
1508         assert(lst);
1509         for (auto& a : v)
1510         {
1511           signature< A >::set(lst, a);
1512         }
1513       }
1514
1515       /**
1516        * @brief Marshals value from marshalled type into variable v
1517        */
1518       static bool get(const DBusWrapper::MessageIterPtr& iter, std::vector< A >& v)
1519       {
1520         auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1521         if (!s) return false;
1522         v.clear();
1523         A a;
1524         while (signature< A >::get(s, a))
1525           v.push_back(std::move(a));
1526
1527         return true;
1528       }
1529     };
1530
1531     /**
1532      * @brief Signature class for marshalling std::array template type
1533      *
1534      * This marshals container's content as DBUS a ascii character type code.
1535      */
1536     template < typename A, size_t N >
1537     struct signature< std::array< A, N > >
1538     {
1539       /**
1540        * @brief Returns name of type marshalled, for informative purposes
1541        */
1542       static std::string name()
1543       {
1544         return "array<" + signature< A >::name() + ", " + std::to_string(N) + ">";
1545       }
1546
1547       /**
1548        * @brief Returns DBUS' signature of type marshalled
1549        */
1550       static std::string sig()
1551       {
1552         return "a" + signature< A >::sig();
1553       }
1554
1555       /**
1556        * @brief Marshals value v as marshalled type into message
1557        */
1558       static void set(const DBusWrapper::MessageIterPtr& iter, const std::array< A, N >& v)
1559       {
1560         auto lst = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'a', signature< A >::sig());
1561         assert(lst);
1562         for (auto& a : v)
1563         {
1564           signature< A >::set(lst, a);
1565         }
1566       }
1567
1568       /**
1569        * @brief Marshals value from marshalled type into variable v
1570        */
1571       static bool get(const DBusWrapper::MessageIterPtr& iter, std::array< A, N >& v)
1572       {
1573         auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1574         if (!s)
1575           return false;
1576         for (auto& a : v)
1577         {
1578           if (!signature< A >::get(s, a))
1579             return false;
1580         }
1581         return true;
1582       }
1583     };
1584
1585     /**
1586      * @brief Signature class for marshalling EldbusVariant type
1587      *
1588      * This marshals variant's content as DBUS v ascii character type code.
1589      */
1590     template < typename A >
1591     struct signature< EldbusVariant< A > >
1592     {
1593       /**
1594        * @brief Returns name of type marshalled, for informative purposes
1595        */
1596       static std::string name()
1597       {
1598         return "variant<" + signature< A >::name() + ">";
1599       }
1600
1601       /**
1602        * @brief Returns DBUS' signature of type marshalled
1603        */
1604       static std::string sig()
1605       {
1606         return "v";
1607       }
1608
1609       /**
1610        * @brief Marshals value v as marshalled type into message
1611        */
1612       static void set(const DBusWrapper::MessageIterPtr& iter, const EldbusVariant< A >& v)
1613       {
1614         set(iter, v.value);
1615       }
1616
1617       /**
1618        * @brief Marshals value v as marshalled type into message
1619        */
1620       static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1621       {
1622         auto var = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'v', signature< A >::sig());
1623         signature< A >::set(var, v);
1624       }
1625
1626       /**
1627        * @brief Marshals value from marshalled type into variable v
1628        */
1629       static bool get(const DBusWrapper::MessageIterPtr& iter, EldbusVariant< A >& v)
1630       {
1631         auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'v');
1632         if (!s)
1633           return false;
1634         return signature< A >::get(s, v.value);
1635       }
1636     };
1637
1638     /**
1639      * @brief Signature class for marshalling std::unordered_map template type
1640      *
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.
1647      */
1648     template < typename A, typename B >
1649     struct signature< std::unordered_map< A, B > >
1650     {
1651       /**
1652        * @brief Returns name of type marshalled, for informative purposes
1653        */
1654       static std::string name()
1655       {
1656         return "unordered_map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
1657       }
1658
1659       /**
1660        * @brief Returns DBUS' signature of type marshalled
1661        */
1662       static std::string sig()
1663       {
1664         return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
1665       }
1666
1667       /**
1668        * @brief Marshals value v as marshalled type into message
1669        */
1670       static void set(const DBusWrapper::MessageIterPtr& iter, const std::unordered_map< A, B >& v)
1671       {
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);
1674         assert(lst);
1675         for (auto& a : v)
1676         {
1677           signature< std::pair< A, B > >::set(lst, a, true);
1678         }
1679       }
1680
1681       /**
1682        * @brief Marshals value from marshalled type into variable v
1683        */
1684       static bool get(const DBusWrapper::MessageIterPtr& iter, std::unordered_map< A, B >& v)
1685       {
1686         auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1687         v.clear();
1688         if (!s)
1689           return false;
1690         std::pair< A, B > a;
1691         while (signature< std::pair< A, B > >::get(s, a))
1692           v.insert(std::move(a));
1693         return true;
1694       }
1695     };
1696
1697     /**
1698      * @brief Signature class for marshalling std::unordered_map template type
1699      *
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.
1706      */
1707     template < typename A, typename B >
1708     struct signature< std::map< A, B > >
1709     {
1710       /**
1711        * @brief Returns name of type marshalled, for informative purposes
1712        */
1713       static std::string name()
1714       {
1715         return "map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
1716       }
1717
1718       /**
1719        * @brief Returns DBUS' signature of type marshalled
1720        */
1721       static std::string sig()
1722       {
1723         return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
1724       }
1725
1726       /**
1727        * @brief Marshals value v as marshalled type into message
1728        */
1729       static void set(const DBusWrapper::MessageIterPtr& iter, const std::map< A, B >& v)
1730       {
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);
1733         assert(lst);
1734         for (auto& a : v)
1735         {
1736           signature< std::pair< A, B > >::set(lst, a, true);
1737         }
1738       }
1739
1740       /**
1741        * @brief Marshals value from marshalled type into variable v
1742        */
1743       static bool get(const DBusWrapper::MessageIterPtr& iter, std::map< A, B >& v)
1744       {
1745         auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1746         if (!s)
1747           return false;
1748         std::pair< A, B > a;
1749         while (signature< std::pair< A, B > >::get(s, a))
1750           v.insert(std::move(a));
1751         return true;
1752       }
1753     };
1754
1755     /**
1756      * @brief Signature helper class for marshalling const reference types
1757      */
1758     template < typename A >
1759     struct signature< const A& >
1760     {
1761       /**
1762        * @brief Returns name of type marshalled, for informative purposes
1763        */
1764       static std::string name()
1765       {
1766         return "const " + signature< A >::name() + "&";
1767       }
1768
1769       /**
1770        * @brief Returns DBUS' signature of type marshalled
1771        */
1772       static std::string sig()
1773       {
1774         return signature< A >::sig();
1775       }
1776
1777       /**
1778        * @brief Marshals value v as marshalled type into message
1779        */
1780       static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1781       {
1782         signature< A >::set(iter, v);
1783       }
1784
1785       /**
1786        * @brief Marshals value from marshalled type into variable v
1787        */
1788       static void get(const DBusWrapper::MessageIterPtr& iter, A& v)
1789       {
1790         signature< A >::get(iter, v);
1791       }
1792     };
1793
1794     /**
1795      * @brief Signature helper class for marshalling reference types
1796      */
1797     template < typename A >
1798     struct signature< A& >
1799     {
1800       /**
1801        * @brief Returns name of type marshalled, for informative purposes
1802        */
1803       static std::string name()
1804       {
1805         return signature< A >::name() + "&";
1806       }
1807
1808       /**
1809        * @brief Returns DBUS' signature of type marshalled
1810        */
1811       static std::string sig()
1812       {
1813         return signature< A >::sig();
1814       }
1815
1816       /**
1817        * @brief Marshals value v as marshalled type into message
1818        */
1819       static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1820       {
1821         signature< A >::set(iter, v);
1822       }
1823
1824       /**
1825        * @brief Marshals value from marshalled type into variable v
1826        */
1827       static void get(const DBusWrapper::MessageIterPtr& iter, A& v)
1828       {
1829         signature< A >::get(iter, v);
1830       }
1831     };
1832
1833     /**
1834      * @brief Signature helper class for marshalling const types
1835      */
1836     template < typename A >
1837     struct signature< const A >
1838     {
1839       /**
1840        * @brief Returns name of type marshalled, for informative purposes
1841        */
1842       static std::string name()
1843       {
1844         return "const " + signature< A >::name();
1845       }
1846
1847       /**
1848        * @brief Returns DBUS' signature of type marshalled
1849        */
1850       static std::string sig()
1851       {
1852         return signature< A >::sig();
1853       }
1854
1855       /**
1856        * @brief Marshals value v as marshalled type into message
1857        */
1858       static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1859       {
1860         signature< A >::set(iter, v);
1861       }
1862
1863       /**
1864        * @brief Marshals value from marshalled type into variable v
1865        */
1866       static void get(const DBusWrapper::MessageIterPtr& iter, A& v)
1867       {
1868         signature< A >::get(iter, v);
1869       }
1870     };
1871
1872     using CallId = DBusWrapper::CallId;
1873
1874     template < typename ValueType >
1875     ValueType unpackValues(CallId callId, const DBusWrapper::MessagePtr& msg)
1876     {
1877       auto iter = DBUS_W->eldbus_message_iter_get_impl(msg, false);
1878       ValueType r;
1879
1880       if (iter)
1881       {
1882         if (!signature< ValueType >::get(iter, r))
1883         {
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() + "'" };
1887         }
1888       }
1889       else
1890       {
1891         r = Error{ "call " + std::to_string(callId.id) + ": failed to get iterator" };
1892       }
1893       return r;
1894     }
1895
1896     inline void packValues_helper(const DBusWrapper::MessageIterPtr&) {}
1897
1898     template < typename A, typename... ARGS >
1899     void packValues_helper(const DBusWrapper::MessageIterPtr& iter, A&& a, ARGS&&... r)
1900     {
1901       signature< A >::set(iter, std::forward< A >(a));
1902       packValues_helper(iter, std::forward< ARGS >(r)...);
1903     }
1904
1905     template < typename... ARGS >
1906     void packValues(CallId callId, const DBusWrapper::MessagePtr& msg, ARGS&&... r)
1907     {
1908       auto iter = DBUS_W->eldbus_message_iter_get_impl(msg, true);
1909       packValues_helper(iter, std::forward< ARGS >(r)...);
1910     }
1911
1912     template < typename >
1913     struct ReturnType;
1914     template < typename R, typename... ARGS >
1915     struct ReturnType< R(ARGS...) >
1916     {
1917       using type = R;
1918     };
1919
1920     template < typename R, typename... ARGS >
1921     struct ReturnType< std::function< R(ARGS...) > >
1922     {
1923       using type = R;
1924     };
1925
1926     template < int... >
1927     struct sequence
1928     {
1929     };
1930
1931     template < int N, int... S >
1932     struct sequence_gen : sequence_gen< N - 1, N - 1, S... >
1933     {
1934     };
1935
1936     template < int... S >
1937     struct sequence_gen< 0, S... >
1938     {
1939       typedef sequence< S... > type;
1940     };
1941
1942     template < typename C, typename... ARGS >
1943     struct apply_helper
1944     {
1945       const std::function< C >& c;
1946       const std::tuple< ARGS... >& args;
1947
1948       template < int... S >
1949       auto apply_2(sequence< S... >) const -> decltype(c(std::get< S >(args)...))
1950       {
1951         return c(std::get< S >(args)...);
1952       }
1953       auto apply_1() const -> decltype(apply_2(typename sequence_gen< sizeof...(ARGS) >::type()))
1954       {
1955         return apply_2(typename sequence_gen< sizeof...(ARGS) >::type());
1956       }
1957     };
1958
1959     template < typename C, typename A, typename... ARGS >
1960     struct apply_helper_2
1961     {
1962       const std::function< C >& c;
1963       const A& a;
1964       const std::tuple< ARGS... >& args;
1965
1966       template < int... S >
1967       auto apply_2(sequence< S... >) const -> decltype(c(a, std::get< S >(args)...))
1968       {
1969         return c(a, std::get< S >(args)...);
1970       }
1971       auto apply_1() const -> decltype(apply_2(typename sequence_gen< sizeof...(ARGS) >::type()))
1972       {
1973         return apply_2(typename sequence_gen< sizeof...(ARGS) >::type());
1974       }
1975     };
1976
1977     template < typename C, typename... ARGS >
1978     auto apply(const std::function< C >& c, const std::tuple< ARGS... >& args) -> typename ReturnType< C >::type
1979     {
1980       apply_helper< C, ARGS... > ah{ c, args };
1981       return ah.apply_1();
1982     }
1983
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
1986     {
1987       apply_helper_2< C, D, ARGS... > ah{ c, d, args };
1988       return ah.apply_1();
1989     }
1990
1991     struct ConnectionState
1992     {
1993       DBusWrapper::ConnectionPtr connection;
1994       DBusWrapper::ObjectPtr object;
1995       DBusWrapper::ProxyPtr proxy, propertiesProxy;
1996     };
1997
1998     template < typename RETTYPE, typename... ARGS >
1999     RETTYPE call(CallId callId, const ConnectionState& connectionState, bool property, const std::string& funcName, const ARGS&... args)
2000     {
2001       const auto& proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
2002       if (!proxy)
2003       {
2004         DBUS_DEBUG("call %d: not initialized", callId.id);
2005         return Error{ "not initialized" };
2006       }
2007
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);
2010       if (!msg)
2011       {
2012         DBUS_DEBUG("call %d: failed", callId.id);
2013         return Error{ "failed to create message" };
2014       }
2015
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());
2019       if (!reply)
2020       {
2021         DBUS_DEBUG("call %d: failed", callId.id);
2022         return Error{ "eldbus returned null as reply" };
2023       }
2024       std::string errname, errmsg;
2025       if (DBUS_W->eldbus_message_error_get_impl(reply, errname, errmsg))
2026       {
2027         DBUS_DEBUG("call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str());
2028         return Error{ errname + ": " + errmsg };
2029       }
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);
2033     }
2034
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)
2039     {
2040       const auto& proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
2041       if (!proxy)
2042       {
2043         DBUS_DEBUG("call %d: not initialized", callId.id);
2044         callback(Error{ "not initialized" });
2045         return;
2046       }
2047
2048       auto msg = DBUS_W->eldbus_proxy_method_call_new_impl(proxy, funcName);
2049       if (!msg)
2050       {
2051         DBUS_DEBUG("call %d: failed", callId.id);
2052         callback(Error{ "failed to create message" });
2053         return;
2054       }
2055
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);
2059         if (!reply)
2060         {
2061           DBUS_DEBUG("call %d: failed", callId.id);
2062           callback(Error{ "eldbus returned null as reply" });
2063         }
2064         else
2065         {
2066           std::string errname, errmsg;
2067           if (DBUS_W->eldbus_message_error_get_impl(reply, errname, errmsg))
2068           {
2069             DBUS_DEBUG("call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str());
2070             callback(Error{ errname + ": " + errmsg });
2071           }
2072           else
2073           {
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));
2077           }
2078         }
2079         }
2080       );
2081       if (pending)
2082       {
2083         DBUS_DEBUG("call %d: call sent", callId.id);
2084       }
2085       else
2086       {
2087         DBUS_DEBUG("call %d: failed to send call", callId.id);
2088         callback(Error{ "failed to send call" });
2089       }
2090     }
2091
2092     inline void displayDebugCallInfo(CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName)
2093     {
2094       DBUS_DEBUG("call %d: %s iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str());
2095     }
2096
2097     inline void displayDebugCallInfoSignal(CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName)
2098     {
2099       DBUS_DEBUG("call %d: %s signal iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str());
2100     }
2101
2102     inline void displayDebugCallInfoProperty(CallId callId, const std::string& funcName, std::string info, const std::string& interfaceName,
2103       const std::string& propertyName)
2104     {
2105       DBUS_DEBUG("call %d: %s iname = %s pname = %s", callId.id, info.c_str(), interfaceName.c_str(), propertyName.c_str());
2106     }
2107
2108     using StringStorage = DBusWrapper::StringStorage;
2109
2110     template < typename A, typename... ARGS >
2111     struct EldbusArgGenerator_Helper
2112     {
2113       static void add(std::vector< std::pair<std::string, std::string> >& r)
2114       {
2115         auto s = r.size();
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);
2121       }
2122     };
2123
2124     template <>
2125     struct EldbusArgGenerator_Helper< void >
2126     {
2127       static void add(std::vector< std::pair<std::string, std::string> >&)
2128       {
2129       }
2130     };
2131
2132     template <>
2133     struct EldbusArgGenerator_Helper< ValueOrError< void >, void >
2134     {
2135       static void add(std::vector< std::pair<std::string, std::string> >&)
2136       {
2137       }
2138     };
2139     template <>
2140     struct EldbusArgGenerator_Helper< ValueOrError<>, void >
2141     {
2142       static void add(std::vector< std::pair<std::string, std::string> >&)
2143       {
2144       }
2145     };
2146
2147     template < typename... ARGS >
2148     struct EldbusArgGenerator_Helper< std::tuple< ARGS... > >
2149     {
2150       static void add(std::vector< std::pair<std::string, std::string> >& r)
2151       {
2152         EldbusArgGenerator_Helper< ARGS..., void >::add(r);
2153       }
2154     };
2155
2156     template < typename RetType >
2157     struct dbus_interface_return_type_traits
2158     {
2159       using type = ValueOrError< RetType >;
2160     };
2161
2162     template < typename... ARGS >
2163     struct dbus_interface_return_type_traits< ValueOrError< ARGS... > >
2164     {
2165       using type = ValueOrError< ARGS... >;
2166     };
2167
2168     template < typename T >
2169     struct dbus_interface_traits;
2170     template < typename RetType, typename... ARGS >
2171     struct dbus_interface_traits< RetType(ARGS...) >
2172     {
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... >;
2177     };
2178
2179     template < typename T >
2180     struct EldbusArgGenerator_Args;
2181     template < typename RetType, typename... ARGS >
2182     struct EldbusArgGenerator_Args< RetType(ARGS...) >
2183     {
2184       static std::string name()
2185       {
2186         return signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::name();
2187       }
2188       static std::vector< std::pair<std::string, std::string> > get()
2189       {
2190         std::vector< std::pair<std::string, std::string> > tmp;
2191         EldbusArgGenerator_Helper< ARGS..., void >::add(tmp);
2192         return tmp;
2193       }
2194     };
2195
2196     template < typename T >
2197     struct EldbusArgGenerator_ReturnType;
2198     template < typename RetType, typename... ARGS >
2199     struct EldbusArgGenerator_ReturnType< RetType(ARGS...) >
2200     {
2201       static std::string name()
2202       {
2203         return signature< RetType >::name();
2204       }
2205       static std::vector< std::pair<std::string, std::string> > get()
2206       {
2207         std::vector< std::pair<std::string, std::string> > tmp;
2208         EldbusArgGenerator_Helper< RetType, void >::add(tmp);
2209         return tmp;
2210       }
2211     };
2212
2213     template < typename T >
2214     struct EldbusArgGenerator_ReturnType;
2215     template < typename... ARGS >
2216     struct EldbusArgGenerator_ReturnType< void(ARGS...) >
2217     {
2218       static std::string name()
2219       {
2220         return "";
2221       }
2222       static std::vector< std::pair<std::string, std::string> > get()
2223       {
2224         return {};
2225       }
2226     };
2227
2228   }
2229
2230   using ConnectionType = DBusWrapper::ConnectionType;
2231
2232   /**
2233    * @brief Class representing client's end of DBUS connection
2234    *
2235    * Allows calling (synchronous and asynchronous) methods on selected interface
2236    * Allows (synchronous and asynchronous) setting / getting properties.
2237    * Allows registering signals.
2238    */
2239   class DBusClient
2240   {
2241     struct ConnectionInfo
2242     {
2243       std::string interfaceName, busName, pathName;
2244     };
2245   public:
2246     /**
2247      * @brief Default constructor, creates non-connected object.
2248      */
2249     DBusClient() = default;
2250
2251     /**
2252      * @brief Connects to dbus choosen by tp, using given arguments
2253      *
2254      * @param bus_name name of the bus to connect to
2255      * @param path_name object's path
2256      * @param interface_name interface name
2257      */
2258     DBusClient(std::string busName_, std::string pathName_, std::string interfaceName_,
2259       ConnectionType tp);
2260
2261     /**
2262      * @brief Connects to dbus using connection conn
2263      *
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
2268      */
2269     DBusClient(std::string busName_, std::string pathName_, std::string interfaceName_,
2270       const DBusWrapper::ConnectionPtr& conn = {});
2271
2272     /**
2273      * @brief Destructor object.
2274      *
2275      * All signals added will be disconnected.
2276      * All asynchronous calls will be cancelled, their callback's will be called
2277      * with failure message.
2278      */
2279     ~DBusClient() = default;
2280     DBusClient(const DBusClient&) = delete;
2281     DBusClient(DBusClient&&) = default;
2282
2283     DBusClient& operator=(DBusClient&&) = default;
2284     DBusClient& operator=(const DBusClient&) = delete;
2285
2286     /**
2287      * @brief bool operator
2288      *
2289      * Returns true, if object is connected to DBUS
2290      */
2291     explicit operator bool() const
2292     {
2293       return bool(connectionState->proxy);
2294     }
2295
2296     /**
2297      * @brief Helper class for calling a method
2298      *
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.
2305      */
2306     template < typename T >
2307     struct Method
2308     {
2309       using RetType = typename detail::dbus_interface_traits< T >::Ret;
2310       const detail::ConnectionState& connectionState;
2311       std::string funcName;
2312       std::string info;
2313       std::shared_ptr< ConnectionInfo > connectionInfo;
2314
2315       /**
2316        * @brief Executes synchronous call on DBUS's method
2317        *
2318        * The function returns ValueOrError<...> object, which
2319        * contains either received values or error message.
2320        *
2321        * @param args arguments to pass to the method
2322        */
2323       template < typename... ARGS >
2324       RetType call(const ARGS&... args)
2325       {
2326         detail::CallId callId;
2327         detail::displayDebugCallInfo(callId, funcName, info, connectionInfo->interfaceName);
2328         return detail::call< RetType >(callId, connectionState, false, funcName, args...);
2329       }
2330
2331       /**
2332        * @brief Executes asynchronous call on DBUS's method
2333        *
2334        * The function calls callback with either received values or error message.
2335        *
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
2338        */
2339       template < typename... ARGS >
2340       void asyncCall(std::function< void(RetType) > callback, const ARGS&... args)
2341       {
2342         detail::CallId callId;
2343         detail::displayDebugCallInfo(callId, funcName, info, connectionInfo->interfaceName);
2344         detail::asyncCall< RetType >(callId, connectionState, false, funcName, std::move(callback), args...);
2345       }
2346     };
2347
2348     /**
2349      * @brief Helper class for calling a property
2350      *
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.
2354      */
2355     template < typename T >
2356     struct Property
2357     {
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;
2362       std::string info;
2363       std::shared_ptr< ConnectionInfo > connectionInfo;
2364
2365       /**
2366        * @brief executes synchronous get on property
2367        *
2368        * The function returns ValueOrError<...> object, which
2369        * contains either received values or error message.
2370        */
2371       RetType get()
2372       {
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);
2376         if (!z)
2377           return z.getError();
2378         return { std::get< 0 >(z.getValues()).value };
2379       }
2380
2381       /**
2382        * @brief executes asynchronous get on property
2383        *
2384        * The function calls callback with either received values or error message.
2385        *
2386        * @param callback callback functor, which will be called with return value(s) or error message
2387        */
2388       void asyncGet(std::function< void(RetType) > callback)
2389       {
2390         detail::CallId callId;
2391         detail::displayDebugCallInfoProperty(callId, "Get", info, connectionInfo->interfaceName, propName);
2392         auto cc = [callback](VariantRetType reply) {
2393           if (reply)
2394             callback(std::move(std::get< 0 >(reply.getValues()).value));
2395           else
2396             callback(reply.getError());
2397         };
2398         detail::asyncCall< VariantRetType >(callId, connectionState, true, "Get", std::move(cc), connectionInfo->interfaceName, propName);
2399       }
2400
2401       /**
2402        * @brief executes synchronous set on property
2403        *
2404        * The function returns ValueOrError<void> object, with
2405        * possible error message.
2406        */
2407       ValueOrError< void > set(const T& r)
2408       {
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);
2413       }
2414
2415       /**
2416        * @brief executes asynchronous get on property
2417        *
2418        * The function calls callback with either received values or error message.
2419        *
2420        * @param callback callback functor, which will be called with return value(s) or error message
2421        */
2422       void asyncSet(std::function< void(ValueOrError< void >) > callback, const T& r)
2423       {
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);
2428       }
2429     };
2430
2431     /**
2432      * @brief Constructs Property<...> object for calling properties
2433      *
2434      * The function constructs and returns proxy object for calling property.
2435      *
2436      * @param propName property name to set and / or query
2437      */
2438     template < typename PropertyType >
2439     Property< PropertyType > property(std::string propName)
2440     {
2441       return Property< PropertyType >{*connectionState, std::move(propName), info, connectionInfo};
2442     }
2443
2444     /**
2445      * @brief Constructs Method<...> object for calling methods
2446      *
2447      * The function constructs and returns proxy object for calling method.
2448      *
2449      * @param funcName function name to call
2450      */
2451     template < typename MethodType >
2452     Method< MethodType > method(std::string funcName)
2453     {
2454       return Method< MethodType >{*connectionState, std::move(funcName), info, connectionInfo};
2455     }
2456
2457     /**
2458      * @brief Registers notification callback, when property has changed
2459      *
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.
2463      */
2464     template < typename V >
2465     void addPropertyChangedEvent(std::string propertyName, std::function< void(V) > callback)
2466     {
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) {
2473           V val = 0;
2474           if (!getFromEinaValue(newValue, &val))
2475           {
2476             DBUS_DEBUG("unable to get property's value");
2477             return;
2478           }
2479           callback(val);
2480         });
2481     }
2482
2483     /**
2484      * @brief Registers callback on the DBUS' signal
2485      *
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.
2489      *
2490      * @param signalName name of the signal to register
2491      * @param callback callback to call
2492      */
2493     template < typename SignalType >
2494     void addSignal(std::string signalName, std::function< SignalType > callback)
2495     {
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))
2502           {
2503             DBUS_DEBUG("call %d: Eldbus error: %s %s", callId.id, errname.c_str(), aux.c_str());
2504             return;
2505           }
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);
2509           if (!params)
2510           {
2511             DBUS_DEBUG("call %d: failed: %s", callId.id, params.getError().message.c_str());
2512             return;
2513           }
2514           try
2515           {
2516             detail::apply(callback, params.getValues());
2517           }
2518           catch (...)
2519           {
2520             DBUS_DEBUG("unhandled exception");
2521             assert(0);
2522           }
2523         });
2524     }
2525
2526   private:
2527     std::unique_ptr<detail::ConnectionState> connectionState{ new detail::ConnectionState };
2528     std::string info;
2529     std::shared_ptr< ConnectionInfo > connectionInfo;
2530
2531     static bool getFromEinaValue(const _Eina_Value* v, void* dst);
2532   };
2533
2534   /**
2535    * @brief Helper class describing DBUS's server interface
2536    *
2537    */
2538   class DBusInterfaceDescription
2539   {
2540     friend class DBusServer;
2541
2542   public:
2543     using MethodInfo = DBusWrapper::MethodInfo;
2544     using SignalInfo = DBusWrapper::SignalInfo;
2545     using PropertyInfo = DBusWrapper::PropertyInfo;
2546     using SignalId = DBusWrapper::SignalId;
2547
2548     /**
2549      * @brief Creates empty interface description with given name
2550      *
2551      * @param interfaceName name of the interface
2552      */
2553     DBusInterfaceDescription(std::string interfaceName);
2554
2555     /**
2556      * @brief adds new, synchronous method to the interface
2557      *
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.
2562      *
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.
2569      *
2570      * @param memberName name of the method
2571      * @param callback functor, which will be called
2572      */
2573     template < typename T >
2574     void addMethod(const std::string& memberName, typename detail::dbus_interface_traits< T >::SyncCB callback)
2575     {
2576       detail::CallId callId;
2577       MethodInfo mi;
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);
2587       z.id = callId;
2588     }
2589
2590     /**
2591      * @brief adds new, synchronous property to the interface
2592      *
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.
2597      *
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.
2601      *
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
2605      */
2606     template < typename T >
2607     void addProperty(const std::string& memberName, std::function< ValueOrError< T >() > getter, std::function< ValueOrError< void >(T) > setter)
2608     {
2609       properties.push_back({});
2610       auto& z = properties.back();
2611       z.memberName = memberName;
2612       z.typeSignature = detail::signature< T >::sig();
2613       if (getter)
2614       {
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 {
2619           try
2620           {
2621             auto v = detail::apply(getter, std::tuple<>{});
2622             if (v)
2623             {
2624               detail::signature< T >::set(dst, std::get< 0 >(v.getValues()));
2625               DBUS_DEBUG("call %d: success", getterId.id);
2626               return "";
2627             }
2628             DBUS_DEBUG("call %d: failed: %s", getterId.id, v.getError().message.c_str());
2629             return v.getError().message;
2630           }
2631           catch (std::exception & e)
2632           {
2633             return std::string("unhandled exception (") + e.what() + ")";
2634           }
2635           catch (...)
2636           {
2637             return "unhandled exception";
2638           }
2639         };
2640       }
2641       if (setter)
2642       {
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)))
2650           {
2651             try
2652             {
2653               auto v = detail::apply(setter, std::move(value));
2654               if (v)
2655               {
2656                 DBUS_DEBUG("call %d: success", setterId.id);
2657                 return "";
2658               }
2659               DBUS_DEBUG("call %d: failed: %s", setterId.id, v.getError().message.c_str());
2660               return v.getError().message;
2661             }
2662             catch (std::exception & e)
2663             {
2664               return std::string("unhandled exception (") + e.what() + ")";
2665             }
2666             catch (...)
2667             {
2668               return "unhandled exception";
2669             }
2670           }
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() + "'";
2675         };
2676       }
2677     }
2678
2679     /**
2680      * @brief adds new signal to the interface
2681      *
2682      * Template types ARGS defines values, which will be emited with the signal
2683      *
2684      * @param memberName name of the method
2685      */
2686     template < typename... ARGS >
2687     SignalId addSignal(const std::string& memberName)
2688     {
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);
2694       z.id = callId;
2695       DBUS_DEBUG("call %d: signal %s", callId.id, memberName.c_str());
2696       return SignalId{ callId };
2697     }
2698
2699   private:
2700     std::vector< MethodInfo > methods;
2701     std::vector< PropertyInfo > properties;
2702     std::vector< SignalInfo > signals;
2703     std::string interfaceName;
2704
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)
2708     {
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);
2714         if (args)
2715         {
2716           try
2717           {
2718             auto v = detail::apply(callback, std::move(args.getValues()));
2719             if (v)
2720             {
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);
2724             }
2725             else
2726             {
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);
2729             }
2730           }
2731           catch (std::exception & e)
2732           {
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);
2736           }
2737           catch (...)
2738           {
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");
2741           }
2742         }
2743         else
2744         {
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);
2750         }
2751         return ret;
2752       };
2753     }
2754   };
2755
2756   /**
2757    * @brief Class representing server's end of DBUS connection
2758    *
2759    * Allows listening (synchronously and asynchronously) on methods on selected interface
2760    * Allows listening (synchronously and asynchronously) on setting / getting properties.
2761    * Allows emiting signals.
2762    */
2763   class DBusServer
2764   {
2765   public:
2766     /**
2767      * @brief Constructs non-connected dbus server.
2768      */
2769     DBusServer() = default;
2770
2771     /**
2772      * @brief Constructs dbus server on either system or user dbus connection.
2773      */
2774     DBusServer(ConnectionType tp);
2775
2776     /**
2777      * @brief Constructs dbus server on connection from getDBusConnectionByType
2778      */
2779     DBusServer(const DBusWrapper::ConnectionPtr& conn);
2780
2781     /**
2782      * @brief Destructor
2783      *
2784      * Destructor will properly destroy everything. Destructor will cancel
2785      * pending replies.
2786      */
2787     ~DBusServer() = default;
2788
2789     DBusServer(const DBusServer&) = delete;
2790     DBusServer(DBusServer&&) = default;
2791
2792     DBusServer& operator=(DBusServer&&) = default;
2793     DBusServer& operator=(const DBusServer&) = delete;
2794
2795     /**
2796      * @brief Registers interface on given path name
2797      *
2798      * @param pathName path object to register interface on.
2799      * @param dscr
2800      * @param fallback
2801      */
2802     void addInterface(const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback = false);
2803
2804     /**
2805      * @brief Gets bus name of the current connection (must be connected)
2806      */
2807     std::string getBusName() const;
2808
2809     /**
2810      * @brief Returns connection object for this dbus server object
2811      *
2812      * @return connection object
2813      */
2814     DBusWrapper::ConnectionPtr getConnection();
2815
2816     /**
2817      * @brief Emits signal
2818      *
2819      * Emits signal based only on data passed to the function
2820      *
2821      * @param signal identifier of the signal
2822      * @param args values to emit
2823      */
2824     template < typename... ARGS >
2825     void emit2(const std::string& path, const std::string& interfaceName,
2826       const std::string& signalName, const ARGS&... args)
2827     {
2828       auto msg = DBUS_W->eldbus_message_signal_new_impl(path, interfaceName, signalName);
2829       detail::CallId id;
2830       detail::packValues(id, msg, args...);
2831       DBUS_W->eldbus_connection_send_impl(connection, msg);
2832     }
2833
2834     /**
2835      * @brief Returns current object path, when handling call to property / method
2836      *
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:
2841      * \code{.cpp}
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
2846      * };
2847      * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
2848      *   DBusServer::getCurrentObjectPath(); // this will current object's path
2849      *
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));
2852      * };
2853      * \endcode
2854      */
2855     static std::string getCurrentObjectPath() { return currentObjectPath; }
2856
2857     /**
2858      * @brief Returns current connection object, when handling call to property / method
2859      *
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:
2864      * \code{.cpp}
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
2869      * };
2870      * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
2871      *   DBusServer::getCurrentObjectPath(); // this will current object's path
2872      *
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));
2875      * };
2876      * \endcode
2877      */
2878     static const DBusWrapper::ConnectionPtr& getCurrentConnection() { return currentConnection; }
2879
2880     /// \cond
2881     class CurrentObjectSetter
2882     {
2883     public:
2884       CurrentObjectSetter(DBusWrapper::ConnectionPtr con, std::string path)
2885       {
2886         currentObjectPath = std::move(path);
2887         currentConnection = std::move(con);
2888       }
2889       ~CurrentObjectSetter()
2890       {
2891         currentObjectPath = "";
2892         currentConnection = {};
2893       }
2894       CurrentObjectSetter(const CurrentObjectSetter&) = delete;
2895       CurrentObjectSetter(CurrentObjectSetter&&) = delete;
2896       void operator=(const CurrentObjectSetter&) = delete;
2897       void operator=(CurrentObjectSetter&&) = delete;
2898     };
2899
2900   private:
2901     DBusWrapper::ConnectionPtr connection;
2902     struct DestructorObject {
2903       std::vector<std::function<void()>> destructors;
2904       ~DestructorObject() {
2905         for (auto& a : destructors) a();
2906       }
2907     };
2908
2909     std::unique_ptr<DestructorObject> destructorObject{ new DestructorObject() };
2910     static thread_local std::string currentObjectPath;
2911     static thread_local DBusWrapper::ConnectionPtr currentConnection;
2912
2913   };
2914
2915   DBusWrapper::ConnectionPtr getDBusConnectionByType(ConnectionType tp);
2916   DBusWrapper::ConnectionPtr getDBusConnectionByName(const std::string& name);
2917   std::string getConnectionName(const DBusWrapper::ConnectionPtr&);
2918 }
2919
2920 namespace std
2921 {
2922   template < size_t INDEX, typename... ARGS >
2923   inline auto get(DBus::ValueOrError< ARGS... >& v) -> decltype(std::get< INDEX >(v.getValues()))&
2924   {
2925     return std::get< INDEX >(v.getValues());
2926   }
2927
2928   template < size_t INDEX, typename... ARGS >
2929   inline auto get(const DBus::ValueOrError< ARGS... >& v) -> decltype(std::get< INDEX >(v.getValues()))
2930   {
2931     return std::get< INDEX >(v.getValues());
2932   }
2933 }
2934
2935 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H