5e956df8f282c13e406b1a91576f648df374ec3f
[platform/core/uifw/dali-adaptor.git] / dali / dali-bridge / src / DBus.hpp
1 /*
2  * Copyright 2017  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *  http://www.apache.org/licenses/LICENSE-2.0
9
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef DBUS_HPP
18 #define DBUS_HPP
19
20 #include <Eldbus.h>
21 #include <memory>
22
23 #include "Optional.hpp"
24 #include <array>
25 #include <atomic>
26 #include <cstdint>
27 #include <map>
28 #include <sstream>
29 #include <string>
30 #include <thread>
31 #include <tuple>
32 #include <type_traits>
33 #include <unordered_map>
34 #include <vector>
35
36 #define DBUS_DEBUG( ... )                                \
37   do                                                     \
38   {                                                      \
39     DBus::debugPrint( __FILE__, __LINE__, __VA_ARGS__ ); \
40   } while( 0 )
41
42 /**
43  * @brief Template based, single file, wrapper library around eldbus for DBUS based communication.
44  *
45  * Main motivation was missing asynchronous calls in AT-SPI library and difficulties,
46  * when using eldbus from C++.
47  *
48  * The library:
49  * - takes care of marshalling arguments to and from DBUS calls.
50  * - allows synchronous and asynchronous calls.
51  * - allows synchronous and asynchronous listeners on signals.
52  * - manages all involved objects' lifetimes.
53  * - errors are passed as optional-alike objects, no exceptions are used.
54  * - allows setting additional debug-print function for more details about
55  *   what's going on
56  *
57  * DBUS's method signatures (and expected return values) are specified as template argument,
58  * using functor syntax. For example:
59  * \code{.cpp}
60  * auto dbus = DBusClient{ ... };
61  * auto v = dbus.method<std::tuple<int, float>(float, float, std::string)>("foo").call(1.0f, 2.0f, "qwe");
62  * \endcode
63  * means (synchronous) call on dbus object, which takes three arguments (thus making call signature \b dds)
64  * of types float, float and string (float will be automatically converted to double).
65  * Expected return value is std::tuple<int, float>, which gives signature <B>(id)</B> - std::tuple acts
66  * as struct container. Returned value v will be of type ValueOrError<std::tuple<int, float>>.\n
67  * Slightly different (asynchronous) example:
68  * \code{.cpp}
69  * auto dbus = DBusClient{ ... };
70  * std::function<void(ValueOrError<int, float>)> callback;
71  * dbus.method<ValueOrError<int, float>(float, float, std::string)>("foo").asyncCall(callback, 1.0f, 2.0f, "qwe");
72  * \endcode
73  * Now the call takes the same arguments and has the same signature. But expected values are different -
74  * now the signature is simply \b id. ValueOrError acts in this case as placeholder for list of values,
75  * which DBUS allows as return data. The call itself is asynchronous - instead of expecting reply
76  * you need to pass a callback, which will be called either with received data and error message.
77  *
78  * Library is not thread-safe, the same object shouldn't be called from different threads without
79  * synchronization. There's no guarantee, that callbacks will be executed on the same thread.
80  */
81 namespace DBus
82 {
83 /// \cond
84 class DBusServer;
85 class DBusClient;
86 class DBusInterfaceDescription;
87
88 /**
89    * @brief DBus action enumeration
90    *
91    * @param METHOD_CALL DBus is about to call a method on some external target
92    * @param SETTER_CALL DBus is about to call a setter method on some external target
93    * @param GETTER_CALL DBus is about to call a getter method on some external target
94    * @param SIGNAL_RECEIVED DBus just received a signal
95    * @param METHOD_RESPONSE DBus server received a method call
96    * @param SETTER_RESPONSE DBus server received a setter call
97    * @param GETTER_RESPONSE DBus server received a getter call
98    * @param SIGNAL_EMIT DBus server is about to emit a signal
99    */
100 enum class DBusActionType
101 {
102   METHOD_CALL,
103   SETTER_CALL,
104   GETTER_CALL,
105   SIGNAL_RECEIVED,
106   METHOD_RESPONSE,
107   SETTER_RESPONSE,
108   GETTER_RESPONSE,
109   SIGNAL_EMIT,
110 };
111
112 /**
113    * @brief Structure containing information about DBus activity, when calling notification callback
114    *
115    * @param type type of the action
116    * @param path path of the object, that's involved in action
117    * @param interface interface, on which member was acted upon. Note, that in case of getters and setters
118    *        this will be real interface, not org.freedesktop.DBus.Properties
119    * @param member member name, that was involved (either method / setter / getter / signal)
120    */
121 struct DBusAction
122 {
123   const DBusActionType type;
124   const char* const bus = nullptr;
125   const char* const path = nullptr;
126   const char* const interface = nullptr;
127   const char* const member = nullptr;
128
129   DBusAction( const DBusActionType type,
130               const char* const bus = nullptr,
131               const char* const path = nullptr,
132               const char* const interface = nullptr,
133               const char* const member = nullptr ) : type( type ), bus( bus ), path( path ), interface( interface ), member( member ) {}
134 };
135
136 /**
137    * @brief Formats debug message and calls debug printer (if any) with it
138    */
139 void debugPrint( const char* file, size_t line, const char* format, ... );
140
141 /**
142    * @brief Sets debug printer callback, which will be called with debug messages
143    *
144    * Callback will be called in various moments of DBus activity. First value passed to callback
145    * is pointer to text, second it's length. Text is ended with 0 (not counted towards it's size),
146    * user can safely printf it.
147    */
148 void setDebugPrinter( std::function< void( const char*, size_t ) > );
149
150 /**
151    * @brief Sets notification callback about processing of DBus call
152    *
153    * Notification callback can be set independently either on client or server.
154    * On client's side callback will be called, when user calls method / getter / setter
155    * or when client has received a signal.
156    * On server's side callback will be called, when sever has received a request to
157    * handle method / getter / setter or when server is going to emit a signal.
158    * Callback should returns as fast as possible.
159    * User can't call setDBusActionNotifier from inside the callback call -
160    * it will cause a deadlock
161    */
162 void setDBusActionNotifier( std::function< void( DBusAction ) > callback );
163
164 namespace detail
165 {
166 void emitNotification( const char* bus, const char* path, const char* interface, const char* member, DBusActionType type );
167 }
168
169 struct Error
170 {
171   std::string message;
172
173   Error() = default;
174   Error( std::string msg ) : message( std::move( msg ) )
175   {
176     assert( !message.empty() );
177   }
178 };
179 struct Success
180 {
181 };
182 /// \endcond
183
184 /**
185    * @brief Value representing data, that came from DBUS or error message
186    *
187    * Object of this class either helds series of values (of types ARGS...)
188    * or error message. This object will be true in boolean context, if has data
189    * and false, if an error occured.
190    * It's valid to create ValueOrError object with empty argument list or void:
191    * \code{.cpp}
192    * ValueOrError<> v1;
193    * ValueOrError<void> v2;
194    * \endcode
195    * Both mean the same - ValueOrError containing no real data and being a marker,
196    * wherever operation successed or failed and containing possible error message.
197    */
198 template < typename... ARGS >
199 class ValueOrError
200 {
201 public:
202   /**
203      * @brief Empty constructor. Valid only, if all ARGS types are default constructible.
204      */
205   ValueOrError() = default;
206
207   /**
208      * @brief Value constructor.
209      *
210      * This will be initialized as success with passed in values.
211      */
212   ValueOrError( ARGS... t ) : value( std::move( t )... ) {}
213
214   /**
215      * @brief Alternative Value constructor.
216      *
217      * This will be initialized as success with passed in values.
218      */
219   ValueOrError( std::tuple< ARGS... > t ) : value( std::move( t ) ) {}
220
221   /**
222      * @brief Error constructor. This will be initialized as failure with given error message.
223      */
224   ValueOrError( Error e ) : error( std::move( e ) )
225   {
226     assert( !error.message.empty() );
227   }
228
229   /**
230      * @brief bool operator.
231      *
232      * Returns true, if operation was successful (getValues member is callable), or false
233      * when operation failed (getError is callable).
234      */
235   explicit operator bool() const
236   {
237     return error.message.empty();
238   }
239
240   /**
241      * @brief Returns error message object.
242      *
243      * Returns object containing error message associated with the failed operation.
244      * Only callable, if operation actually failed, otherwise will assert.
245      */
246   const Error& getError() const
247   {
248     return error;
249   }
250
251   /**
252      * @brief Returns modifiable tuple of held data.
253      *
254      * Returns reference to the internal tuple containing held data.
255      * User can modify (or move) data safely.
256      * Only callable, if operation actually successed, otherwise will assert.
257      */
258   std::tuple< ARGS... >& getValues()
259   {
260     assert( *this );
261     return value;
262   }
263
264   /**
265      * @brief Returns const tuple of held data.
266      *
267      * Returns const reference to the internal tuple containing held data.
268      * Only callable, if operation actually successed, otherwise will assert.
269      */
270   const std::tuple< ARGS... >& getValues() const
271   {
272     assert( *this );
273     return value;
274   }
275
276 protected:
277   /// \cond
278   std::tuple< ARGS... > value;
279   Error error;
280   /// \endcond
281 };
282
283 /// \cond
284 template <>
285 class ValueOrError<>
286 {
287 public:
288   ValueOrError() = default;
289   ValueOrError( std::tuple<> t ) {}
290   ValueOrError( Error e ) : error( std::move( e ) )
291   {
292     assert( !error.message.empty() );
293   }
294
295   explicit operator bool() const
296   {
297     return error.message.empty();
298   }
299   const Error& getError() const
300   {
301     return error;
302   }
303   std::tuple<>& getValues()
304   {
305     assert( *this );
306     static std::tuple<> t;
307     return t;
308   }
309   std::tuple<> getValues() const
310   {
311     assert( *this );
312     return {};
313   }
314
315 protected:
316   Error error;
317 };
318
319 template <>
320 class ValueOrError< void >
321 {
322 public:
323   ValueOrError() = default;
324   ValueOrError( Success ) {}
325   ValueOrError( Error e ) : error( std::move( e ) )
326   {
327     assert( !error.message.empty() );
328   }
329
330   explicit operator bool() const
331   {
332     return error.message.empty();
333   }
334   const Error& getError() const
335   {
336     return error;
337   }
338   std::tuple<>& getValues()
339   {
340     assert( *this );
341     static std::tuple<> t;
342     return t;
343   }
344   std::tuple<> getValues() const
345   {
346     assert( *this );
347     return {};
348   }
349
350 protected:
351   Error error;
352 };
353 struct ObjectPath
354 {
355   std::string value;
356 };
357 namespace detail
358 {
359 class CallOnDestructionList
360 {
361 public:
362   CallOnDestructionList() = default;
363   CallOnDestructionList( const CallOnDestructionList& ) = delete;
364   CallOnDestructionList( CallOnDestructionList&& ) = default;
365
366   CallOnDestructionList& operator=( const CallOnDestructionList& ) = delete;
367   CallOnDestructionList& operator=( CallOnDestructionList&& );
368
369   void add( const std::function< void() >& c );
370
371 private:
372   std::vector< std::function< void() > > functions;
373 };
374
375 struct caller_eldbus_connection_unref
376 {
377   void operator()( Eldbus_Connection* p ) const
378   {
379     eldbus_connection_unref( p );
380   }
381 };
382
383 struct caller_eldbus_message_unref
384 {
385   void operator()( Eldbus_Message* p ) const
386   {
387     eldbus_message_unref( p );
388   }
389 };
390
391 struct caller_eldbus_proxy_unref
392 {
393   void operator()( Eldbus_Proxy* p ) const
394   {
395     eldbus_proxy_unref( p );
396   }
397 };
398 }
399 /// \endcond
400
401 /**
402    * @brief Class used to marshall DBUS's variant type
403    *
404    * Minimalistic class, that allows user to specify DBUS variant type
405    * as argument or return value. You need to pass real type hidden under variant as
406    * template type \b A. At this point library doesn't allow to expected one of few classes
407    * as return data in variant. So for example user can't specify method call, which on return
408    * expects DBUS variant holding either string or int.
409    */
410 template < typename A >
411 struct EldbusVariant
412 {
413   A value;
414 };
415
416 /// \cond
417 class EldbusConnection
418 {
419   Eldbus_Connection* ptr = nullptr;
420
421 public:
422   EldbusConnection( Eldbus_Connection* c ) : ptr( c )
423   {
424     eldbus_init();
425   }
426   EldbusConnection() = delete;
427   EldbusConnection( const EldbusConnection& ) = delete;
428   EldbusConnection( EldbusConnection&& ) = delete;
429   ~EldbusConnection()
430   {
431     eldbus_connection_unref( ptr );
432     eldbus_shutdown();
433   }
434
435   Eldbus_Connection* get() const
436   {
437     return ptr;
438   }
439 };
440 //using EldbusConnectionCallbackHandle = std::shared_ptr<Eldbus_Connection>;
441 using EldbusMessageCallbackHandle = std::unique_ptr< Eldbus_Message, detail::caller_eldbus_message_unref >;
442 using EldbusObjectCallbackHandle = std::shared_ptr< Eldbus_Object >;
443 using EldbusProxyHandle = std::shared_ptr< Eldbus_Proxy >;
444 /// \endcond
445
446 /**
447    * @brief Namespace for private, internal functions and classes
448    *
449    */
450 namespace detail
451 {
452 /// \cond
453 template < typename T, typename = void >
454 struct signature;
455 template < typename... ARGS >
456 struct signature< std::tuple< ARGS... > >;
457 template < typename A, typename B >
458 struct signature< std::pair< A, B > >;
459 template < typename A >
460 struct signature< std::vector< A > >;
461 template < typename A, size_t N >
462 struct signature< std::array< A, N > >;
463 template < typename A, typename B >
464 struct signature< std::unordered_map< A, B > >;
465 template < typename A, typename B >
466 struct signature< std::map< A, B > >;
467
468 template < typename T >
469 struct signature< T, typename std::enable_if< std::is_enum< T >::value, void >::type >
470 {
471   /**
472       * @brief Returns name of type marshalled, for informative purposes
473       */
474   static std::string name()
475   {
476     return "enum";
477   }
478   /**
479       * @brief Returns DBUS' signature of type marshalled
480       */
481   static std::string sig()
482   {
483     // TODO: add check for failure in marshalling arguments
484     return "i";
485   }
486   /**
487       * @brief Marshals value v as marshalled type into message
488       */
489   static void set( Eldbus_Message_Iter* iter, T v )
490   {
491     eldbus_message_iter_arguments_append( iter, sig().c_str(), static_cast< int >( v ) );
492   }
493   /**
494       * @brief Marshals value from marshalled type into variable v
495       */
496   static bool get( Eldbus_Message_Iter* iter, T& v )
497   {
498     int q;
499     auto z = eldbus_message_iter_get_and_next( iter, sig()[0], &q );
500     v = static_cast< T >( q );
501     return z;
502   }
503 };
504 /// \endcond
505
506 /**
507      * @brief Signature class for marshalling uint8 type.
508      */
509 template <>
510 struct signature< uint8_t >
511 {
512   /**
513       * @brief Returns name of type marshalled, for informative purposes
514       */
515   static std::string name()
516   {
517     return "uint8_t";
518   }
519   /**
520       * @brief Returns DBUS' signature of type marshalled
521       */
522   static std::string sig()
523   {
524     return "y";
525   }
526   /**
527       * @brief Marshals value v as marshalled type into message
528       */
529   static void set( Eldbus_Message_Iter* iter, uint8_t v )
530   {
531     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
532   }
533   /**
534       * @brief Marshals value from marshalled type into variable v
535       */
536   static bool get( Eldbus_Message_Iter* iter, uint8_t& v )
537   {
538     return eldbus_message_iter_get_and_next( iter, sig()[0], &v );
539   }
540 };
541
542 /**
543      * @brief Signature class for marshalling uint16 type.
544      */
545 template <>
546 struct signature< uint16_t >
547 {
548   /**
549       * @brief Returns name of type marshalled, for informative purposes
550       */
551   static std::string name()
552   {
553     return "uint16_t";
554   }
555   /**
556       * @brief Returns DBUS' signature of type marshalled
557       */
558   static std::string sig()
559   {
560     return "q";
561   }
562   /**
563       * @brief Marshals value v as marshalled type into message
564       */
565   static void set( Eldbus_Message_Iter* iter, uint16_t v )
566   {
567     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
568   }
569   /**
570       * @brief Marshals value from marshalled type into variable v
571       */
572   static bool get( Eldbus_Message_Iter* iter, uint16_t& v )
573   {
574     return eldbus_message_iter_get_and_next( iter, sig()[0], &v );
575   }
576 };
577
578 /**
579      * @brief Signature class for marshalling uint32 type.
580      */
581 template <>
582 struct signature< uint32_t >
583 {
584   /**
585       * @brief Returns name of type marshalled, for informative purposes
586       */
587   static std::string name()
588   {
589     return "uint32_t";
590   }
591   /**
592       * @brief Returns DBUS' signature of type marshalled
593       */
594   static std::string sig()
595   {
596     return "u";
597   }
598   /**
599       * @brief Marshals value v as marshalled type into message
600       */
601   static void set( Eldbus_Message_Iter* iter, uint32_t v )
602   {
603     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
604   }
605   /**
606       * @brief Marshals value from marshalled type into variable v
607       */
608   static bool get( Eldbus_Message_Iter* iter, uint32_t& v )
609   {
610     return eldbus_message_iter_get_and_next( iter, sig()[0], &v );
611   }
612 };
613
614 /**
615      * @brief Signature class for marshalling uint64 type.
616      */
617 template <>
618 struct signature< uint64_t >
619 {
620   /**
621       * @brief Returns name of type marshalled, for informative purposes
622       */
623   static std::string name()
624   {
625     return "uint64_t";
626   }
627   /**
628       * @brief Returns DBUS' signature of type marshalled
629       */
630   static std::string sig()
631   {
632     return "t";
633   }
634   /**
635       * @brief Marshals value v as marshalled type into message
636       */
637   static void set( Eldbus_Message_Iter* iter, uint64_t v )
638   {
639     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
640   }
641   /**
642       * @brief Marshals value from marshalled type into variable v
643       */
644   static bool get( Eldbus_Message_Iter* iter, uint64_t& v )
645   {
646     return eldbus_message_iter_get_and_next( iter, sig()[0], &v );
647   }
648 };
649
650 /**
651      * @brief Signature class for marshalling int16 type.
652      */
653 template <>
654 struct signature< int16_t >
655 {
656   /**
657       * @brief Returns name of type marshalled, for informative purposes
658       */
659   static std::string name()
660   {
661     return "int16_t";
662   }
663   /**
664       * @brief Returns DBUS' signature of type marshalled
665       */
666   static std::string sig()
667   {
668     return "n";
669   }
670   /**
671       * @brief Marshals value v as marshalled type into message
672       */
673   static void set( Eldbus_Message_Iter* iter, int16_t v )
674   {
675     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
676   }
677   /**
678       * @brief Marshals value from marshalled type into variable v
679       */
680   static bool get( Eldbus_Message_Iter* iter, int16_t& v )
681   {
682     return eldbus_message_iter_get_and_next( iter, sig()[0], &v );
683   }
684 };
685
686 /**
687      * @brief Signature class for marshalling int32 type.
688      */
689 template <>
690 struct signature< int32_t >
691 {
692   /**
693       * @brief Returns name of type marshalled, for informative purposes
694       */
695   static std::string name()
696   {
697     return "int32_t";
698   }
699   /**
700       * @brief Returns DBUS' signature of type marshalled
701       */
702   static std::string sig()
703   {
704     return "i";
705   }
706   /**
707       * @brief Marshals value v as marshalled type into message
708       */
709   static void set( Eldbus_Message_Iter* iter, int32_t v )
710   {
711     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
712   }
713   /**
714       * @brief Marshals value from marshalled type into variable v
715       */
716   static bool get( Eldbus_Message_Iter* iter, int32_t& v )
717   {
718     return eldbus_message_iter_get_and_next( iter, sig()[0], &v );
719   }
720 };
721
722 /**
723      * @brief Signature class for marshalling int64 type.
724      */
725 template <>
726 struct signature< int64_t >
727 {
728   /**
729       * @brief Returns name of type marshalled, for informative purposes
730       */
731   static std::string name()
732   {
733     return "int64_t";
734   }
735   /**
736       * @brief Returns DBUS' signature of type marshalled
737       */
738   static std::string sig()
739   {
740     return "x";
741   }
742   /**
743       * @brief Marshals value v as marshalled type into message
744       */
745   static void set( Eldbus_Message_Iter* iter, int64_t v )
746   {
747     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
748   }
749   /**
750       * @brief Marshals value from marshalled type into variable v
751       */
752   static bool get( Eldbus_Message_Iter* iter, int64_t& v )
753   {
754     return eldbus_message_iter_get_and_next( iter, sig()[0], &v );
755   }
756 };
757
758 /**
759      * @brief Signature class for marshalling double type.
760      */
761 template <>
762 struct signature< double >
763 {
764   /**
765       * @brief Returns name of type marshalled, for informative purposes
766       */
767   static std::string name()
768   {
769     return "double";
770   }
771   /**
772       * @brief Returns DBUS' signature of type marshalled
773       */
774   static std::string sig()
775   {
776     return "d";
777   }
778   /**
779       * @brief Marshals value v as marshalled type into message
780       */
781   static void set( Eldbus_Message_Iter* iter, double v )
782   {
783     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
784   }
785   /**
786       * @brief Marshals value from marshalled type into variable v
787       */
788   static bool get( Eldbus_Message_Iter* iter, double& v )
789   {
790     return eldbus_message_iter_get_and_next( iter, sig()[0], &v );
791   }
792   /**
793       * @brief Marshals value from marshalled type into variable v
794       */
795   static bool get( Eldbus_Message_Iter* iter, float& v2 )
796   {
797     double v = 0;
798     auto r = eldbus_message_iter_get_and_next( iter, sig()[0], &v );
799     v2 = static_cast< float >( v );
800     return r;
801   }
802 };
803
804 /**
805      * @brief Signature class for marshalling float type.
806      */
807 template <>
808 struct signature< float >
809 {
810   /**
811       * @brief Returns name of type marshalled, for informative purposes
812       */
813   static std::string name()
814   {
815     return "float";
816   }
817   /**
818       * @brief Returns DBUS' signature of type marshalled
819       */
820   static std::string sig()
821   {
822     return "d";
823   }
824   /**
825       * @brief Marshals value v as marshalled type into message
826       */
827   static void set( Eldbus_Message_Iter* iter, float v )
828   {
829     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
830   }
831   /**
832       * @brief Marshals value from marshalled type into variable v
833       */
834   static bool get( Eldbus_Message_Iter* iter, double& v )
835   {
836     return eldbus_message_iter_get_and_next( iter, sig()[0], &v );
837   }
838   /**
839       * @brief Marshals value from marshalled type into variable v
840       */
841   static bool get( Eldbus_Message_Iter* iter, float& v2 )
842   {
843     double v = 0;
844     auto r = eldbus_message_iter_get_and_next( iter, sig()[0], &v );
845     v2 = static_cast< float >( v );
846     return r;
847   }
848 };
849
850 /**
851      * @brief Signature class for marshalling boolean type.
852      */
853 template <>
854 struct signature< bool >
855 {
856   /**
857       * @brief Returns name of type marshalled, for informative purposes
858       */
859   static std::string name()
860   {
861     return "bool";
862   }
863   /**
864       * @brief Returns DBUS' signature of type marshalled
865       */
866   static std::string sig()
867   {
868     return "b";
869   }
870   /**
871       * @brief Marshals value v as marshalled type into message
872       */
873   static void set( Eldbus_Message_Iter* iter, bool v )
874   {
875     eldbus_message_iter_arguments_append( iter, sig().c_str(), v ? 1 : 0 );
876   }
877   /**
878       * @brief Marshals value from marshalled type into variable v
879       */
880   static bool get( Eldbus_Message_Iter* iter, bool& v )
881   {
882     unsigned char q;
883     auto z = eldbus_message_iter_get_and_next( iter, sig()[0], &q );
884     v = q != 0;
885     return z;
886   }
887 };
888
889 /**
890      * @brief Signature class for marshalling string type.
891      *
892      * Both (const) char * and std::string types are accepted as value to send.
893      * Only std::string is accepted as value to receive.
894      */
895 template <>
896 struct signature< std::string >
897 {
898   /**
899       * @brief Returns name of type marshalled, for informative purposes
900       */
901   static std::string name()
902   {
903     return "string";
904   }
905   /**
906       * @brief Returns DBUS' signature of type marshalled
907       */
908   static std::string sig()
909   {
910     return "s";
911   }
912   /**
913       * @brief Marshals value v as marshalled type into message
914       */
915   static void set( Eldbus_Message_Iter* iter, const std::string& v )
916   {
917     eldbus_message_iter_arguments_append( iter, sig().c_str(), v.c_str() );
918   }
919   /**
920       * @brief Marshals value v as marshalled type into message
921       */
922   static void set( Eldbus_Message_Iter* iter, const char* v )
923   {
924     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
925   }
926   /**
927       * @brief Marshals value from marshalled type into variable v
928       */
929   static bool get( Eldbus_Message_Iter* iter, std::string& v )
930   {
931     const char* q;
932     if( !eldbus_message_iter_get_and_next( iter, 's', &q ) )
933     {
934       if( !eldbus_message_iter_get_and_next( iter, 'o', &q ) )
935         return false;
936     }
937     v = q;
938     return true;
939   }
940 };
941 template <>
942 struct signature< ObjectPath >
943 {
944   /**
945       * @brief Returns name of type marshalled, for informative purposes
946       */
947   static std::string name()
948   {
949     return "path";
950   }
951   /**
952       * @brief Returns DBUS' signature of type marshalled
953       */
954   static std::string sig()
955   {
956     return "o";
957   }
958   /**
959       * @brief Marshals value v as marshalled type into message
960       */
961   static void set( Eldbus_Message_Iter* iter, const std::string& v )
962   {
963     eldbus_message_iter_arguments_append( iter, sig().c_str(), v.c_str() );
964   }
965   /**
966       * @brief Marshals value v as marshalled type into message
967       */
968   static void set( Eldbus_Message_Iter* iter, const ObjectPath& v )
969   {
970     eldbus_message_iter_arguments_append( iter, sig().c_str(), v.value.c_str() );
971   }
972   /**
973       * @brief Marshals value v as marshalled type into message
974       */
975   static void set( Eldbus_Message_Iter* iter, const char* v )
976   {
977     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
978   }
979   /**
980       * @brief Marshals value from marshalled type into variable v
981       */
982   static bool get( Eldbus_Message_Iter* iter, ObjectPath& v )
983   {
984     const char* q;
985     if( !eldbus_message_iter_get_and_next( iter, 'o', &q ) )
986       return false;
987     v.value = q;
988     return true;
989   }
990   /**
991       * @brief Marshals value from marshalled type into variable v
992       */
993   static bool get( Eldbus_Message_Iter* iter, std::string& v )
994   {
995     const char* q;
996     if( !eldbus_message_iter_get_and_next( iter, 'o', &q ) )
997       return false;
998     v = q;
999     return true;
1000   }
1001 };
1002
1003 /**
1004      * @brief Signature class for marshalling (const) char * type.
1005      *
1006      * Both (const) char * and std::string types are accepted as value to send.
1007      * You can't use (const) char * variable type to receive value.
1008      */
1009 template <>
1010 struct signature< char* >
1011 {
1012   /**
1013       * @brief Returns name of type marshalled, for informative purposes
1014       */
1015   static std::string name()
1016   {
1017     return "string";
1018   }
1019   /**
1020       * @brief Returns DBUS' signature of type marshalled
1021       */
1022   static std::string sig()
1023   {
1024     return "s";
1025   }
1026   /**
1027       * @brief Marshals value v as marshalled type into message
1028       */
1029   static void set( Eldbus_Message_Iter* iter, const std::string& v )
1030   {
1031     eldbus_message_iter_arguments_append( iter, sig().c_str(), v.c_str() );
1032   }
1033   /**
1034       * @brief Marshals value v as marshalled type into message
1035       */
1036   static void set( Eldbus_Message_Iter* iter, const char* v )
1037   {
1038     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
1039   }
1040 };
1041
1042 /**
1043      * @brief Signature class for marshalling (const) char[N] type.
1044      *
1045      * Both (const) char[N] and std::string types are accepted as value to send.
1046      * You can't use (const) char[N] variable type to receive value.
1047      */
1048 template < size_t N >
1049 struct signature< char[N] >
1050 {
1051   /**
1052       * @brief Returns name of type marshalled, for informative purposes
1053       */
1054   static std::string name()
1055   {
1056     return "string";
1057   }
1058   /**
1059       * @brief Returns DBUS' signature of type marshalled
1060       */
1061   static std::string sig()
1062   {
1063     return "s";
1064   }
1065   /**
1066       * @brief Marshals value v as marshalled type into message
1067       */
1068   static void set( Eldbus_Message_Iter* iter, const std::string& v )
1069   {
1070     eldbus_message_iter_arguments_append( iter, sig().c_str(), v.c_str() );
1071   }
1072   /**
1073       * @brief Marshals value v as marshalled type into message
1074       */
1075   static void set( Eldbus_Message_Iter* iter, const char* v )
1076   {
1077     eldbus_message_iter_arguments_append( iter, sig().c_str(), v );
1078   }
1079 };
1080 /// \cond
1081 template < size_t INDEX, typename A, typename... ARGS >
1082 struct signature_tuple_element_type_helper
1083 {
1084   using type = typename signature_tuple_element_type_helper< INDEX - 1, ARGS... >::type;
1085 };
1086 template < typename A, typename... ARGS >
1087 struct signature_tuple_element_type_helper< 0, A, ARGS... >
1088 {
1089   using type = A;
1090 };
1091 /// \endcond
1092
1093 /**
1094      * @brief Helper class to marshall tuples
1095      *
1096      * This class marshals all elements of the tuple value starting at the index INDEX
1097      * and incrementing. This class recursively calls itself with increasing INDEX value
1098      * until INDEX is equal to SIZE, where recursive calling ends.
1099      */
1100 template < size_t INDEX, size_t SIZE, typename... ARGS >
1101 struct signature_tuple_helper
1102 {
1103   using current_type = typename signature_tuple_element_type_helper< INDEX, ARGS... >::type;
1104
1105   /**
1106       * @brief Returns name of type marshalled, for informative purposes
1107       */
1108   static std::string name()
1109   {
1110     if( INDEX + 1 >= SIZE )
1111       return signature< current_type >::name();
1112     return signature< current_type >::name() + ", " + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::name();
1113   }
1114   /**
1115       * @brief Returns DBUS' signature of type marshalled
1116       */
1117   static std::string sig()
1118   {
1119     return signature< current_type >::sig() + signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::sig();
1120   }
1121   /**
1122       * @brief Marshals value v as marshalled type into message
1123       */
1124   static void set( Eldbus_Message_Iter* iter, const std::tuple< ARGS... >& args )
1125   {
1126     signature< current_type >::set( iter, std::get< INDEX >( args ) );
1127     signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::set( iter, args );
1128   }
1129   /**
1130       * @brief Marshals value from marshalled type into variable v
1131       */
1132   static bool get( Eldbus_Message_Iter* iter, std::tuple< ARGS... >& args )
1133   {
1134     return signature< current_type >::get( iter, std::get< INDEX >( args ) ) &&
1135            signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::get( iter, args );
1136   }
1137 };
1138
1139 /**
1140      * @brief Helper class to marshall tuples
1141      *
1142      * This class marks end of the tuple marshalling. Members of this class are called
1143      * when INDEX value is equal to SIZE.
1144      */
1145 template < size_t SIZE, typename... ARGS >
1146 struct signature_tuple_helper< SIZE, SIZE, ARGS... >
1147 {
1148   /**
1149       * @brief Returns name of type marshalled, for informative purposes
1150       */
1151   static std::string name()
1152   {
1153     return "";
1154   }
1155   /**
1156       * @brief Returns DBUS' signature of type marshalled
1157       */
1158   static std::string sig()
1159   {
1160     return "";
1161   }
1162   /**
1163       * @brief Marshals value v as marshalled type into message
1164       */
1165   static void set( Eldbus_Message_Iter* iter, const std::tuple< ARGS... >& args )
1166   {
1167   }
1168   /**
1169       * @brief Marshals value from marshalled type into variable v
1170       */
1171   static bool get( Eldbus_Message_Iter* iter, std::tuple< ARGS... >& args )
1172   {
1173     return true;
1174   }
1175 };
1176
1177 /**
1178      * @brief Signature class for marshalling tuple of values
1179      *
1180      * This class marshalls tuple of values. This represents
1181      * DBUS struct typle, encoded with character 'r'
1182      */
1183 template < typename... ARGS >
1184 struct signature< std::tuple< ARGS... > >
1185 {
1186   /**
1187       * @brief Returns name of type marshalled, for informative purposes
1188       */
1189   static std::string name()
1190   {
1191     return "tuple<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
1192   }
1193   /**
1194       * @brief Returns DBUS' signature of type marshalled
1195       */
1196   static std::string sig()
1197   {
1198     return "(" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig() + ")";
1199   }
1200   /**
1201       * @brief Marshals value v as marshalled type into message
1202       */
1203   static void set( Eldbus_Message_Iter* iter, const std::tuple< ARGS... >& args )
1204   {
1205     auto entry = eldbus_message_iter_container_new( iter, 'r', NULL );
1206     signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( entry, args );
1207     eldbus_message_iter_container_close( iter, entry );
1208   }
1209   /**
1210       * @brief Marshals value from marshalled type into variable v
1211       */
1212   static bool get( Eldbus_Message_Iter* iter, std::tuple< ARGS... >& args )
1213   {
1214     Eldbus_Message_Iter* entry;
1215     if( !eldbus_message_iter_get_and_next( iter, 'r', &entry ) )
1216       return false;
1217     auto z = signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( entry, args );
1218     return z;
1219   }
1220 };
1221 /**
1222      * @brief Signature class for marshalling ValueOrError template type
1223      *
1224      * ValueOrError template type is used to marshall list of values passed to
1225      * DBUS (or received from) at the "top" level. For example ss(s) is represented as
1226      * \code{.cpp} ValueOrError<std::string, std::string, std::tuple<std::string>> \endcode
1227      * While (ss(s)) is represented as
1228      * \code{.cpp} std::tuple<std::string, std::string, std::tuple<std::string>> \endcode
1229      * or
1230      * \code{.cpp} ValueOrError<std::tuple<std::string, std::string, std::tuple<std::string>>> \endcode
1231      */
1232 template < typename... ARGS >
1233 struct signature< ValueOrError< ARGS... > >
1234 {
1235   /**
1236       * @brief Returns name of type marshalled, for informative purposes
1237       */
1238   static std::string name()
1239   {
1240     return "ValueOrError<" + signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name() + ">";
1241   }
1242   /**
1243       * @brief Returns DBUS' signature of type marshalled
1244       */
1245   static std::string sig()
1246   {
1247     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::sig();
1248   }
1249   /**
1250       * @brief Marshals value v as marshalled type into message
1251       */
1252   static void set( Eldbus_Message_Iter* iter, const ValueOrError< ARGS... >& args )
1253   {
1254     signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::set( iter, args.getValues() );
1255   }
1256   /**
1257       * @brief Marshals value from marshalled type into variable v
1258       */
1259   static bool get( Eldbus_Message_Iter* iter, ValueOrError< ARGS... >& args )
1260   {
1261     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::get( iter, args.getValues() );
1262   }
1263 };
1264 /**
1265      * @brief Signature class for marshalling ValueOrError<void> type
1266      */
1267 template <>
1268 struct signature< ValueOrError< void > >
1269 {
1270   /**
1271       * @brief Returns name of type marshalled, for informative purposes
1272       */
1273   static std::string name()
1274   {
1275     return "ValueOrError<void>";
1276   }
1277   /**
1278       * @brief Returns DBUS' signature of type marshalled
1279       */
1280   static std::string sig()
1281   {
1282     return "";
1283   }
1284   /**
1285       * @brief Marshals value v as marshalled type into message
1286       */
1287   static void set( Eldbus_Message_Iter* iter, const ValueOrError< void >& args )
1288   {
1289   }
1290   /**
1291       * @brief Marshals value from marshalled type into variable v
1292       */
1293   static bool get( Eldbus_Message_Iter* iter, ValueOrError< void >& args )
1294   {
1295     return true;
1296   }
1297 };
1298 /**
1299      * @brief Signature class for marshalling ValueOrError<> type
1300      */
1301 template <>
1302 struct signature< ValueOrError<> >
1303 {
1304   /**
1305       * @brief Returns name of type marshalled, for informative purposes
1306       */
1307   static std::string name()
1308   {
1309     return "ValueOrError<>";
1310   }
1311   /**
1312       * @brief Returns DBUS' signature of type marshalled
1313       */
1314   static std::string sig()
1315   {
1316     return "";
1317   }
1318   /**
1319       * @brief Marshals value v as marshalled type into message
1320       */
1321   static void set( Eldbus_Message_Iter* iter, const ValueOrError<>& args )
1322   {
1323   }
1324   /**
1325       * @brief Marshals value from marshalled type into variable v
1326       */
1327   static bool get( Eldbus_Message_Iter* iter, ValueOrError<>& args )
1328   {
1329     return true;
1330   }
1331 };
1332 /**
1333      * @brief Signature class for marshalling pair of types
1334      */
1335 template < typename A, typename B >
1336 struct signature< std::pair< A, B > >
1337 {
1338   /**
1339       * @brief Returns name of type marshalled, for informative purposes
1340       */
1341   static std::string name()
1342   {
1343     return "pair<" + signature_tuple_helper< 0, 2, A, B >::name() + ">";
1344   }
1345   /**
1346       * @brief Returns DBUS' signature of type marshalled
1347       */
1348   static std::string sig()
1349   {
1350     return "(" + signature_tuple_helper< 0, 2, A, B >::sig() + ")";
1351   }
1352   /**
1353       * @brief Marshals value v as marshalled type into message
1354       */
1355   static void set( Eldbus_Message_Iter* iter, const std::pair< A, B >& ab, bool dictionary = false )
1356   {
1357     auto entry = eldbus_message_iter_container_new( iter, dictionary ? 'e' : 'r', NULL );
1358     signature_tuple_helper< 0, 2, A, B >::set( entry, ab );
1359     eldbus_message_iter_container_close( iter, entry );
1360   }
1361   /**
1362       * @brief Marshals value from marshalled type into variable v
1363       */
1364   static bool get( Eldbus_Message_Iter* iter, std::pair< A, B >& ab )
1365   {
1366     char sg = 'r';
1367     char* t = eldbus_message_iter_signature_get( iter );
1368     if( t && t[0] == '{' )
1369       sg = '{';
1370     free( t );
1371
1372     Eldbus_Message_Iter* entry;
1373     if( !eldbus_message_iter_get_and_next( iter, sg, &entry ) )
1374       return false;
1375     std::tuple< A, B > ab_tmp;
1376     auto z = signature_tuple_helper< 0, 2, A, B >::get( entry, ab_tmp );
1377     if( z )
1378     {
1379       ab.first = std::move( std::get< 0 >( ab_tmp ) );
1380       ab.second = std::move( std::get< 1 >( ab_tmp ) );
1381     }
1382     return z;
1383   }
1384 };
1385 /**
1386      * @brief Signature class for marshalling std::vector template type
1387      *
1388      * This marshals container's content as DBUS a ascii character type code.
1389      */
1390 template < typename A >
1391 struct signature< std::vector< A > >
1392 {
1393   /**
1394       * @brief Returns name of type marshalled, for informative purposes
1395       */
1396   static std::string name()
1397   {
1398     return "vector<" + signature< A >::name() + ">";
1399   }
1400   /**
1401       * @brief Returns DBUS' signature of type marshalled
1402       */
1403   static std::string sig()
1404   {
1405     return "a" + signature< A >::sig();
1406   }
1407   /**
1408       * @brief Marshals value v as marshalled type into message
1409       */
1410   static void set( Eldbus_Message_Iter* iter, const std::vector< A >& v )
1411   {
1412     auto lst = eldbus_message_iter_container_new( iter, 'a', signature< A >::sig().c_str() );
1413     assert( lst );
1414     for( auto& a : v )
1415     {
1416       signature< A >::set( lst, a );
1417     }
1418     eldbus_message_iter_container_close( iter, lst );
1419   }
1420   /**
1421       * @brief Marshals value from marshalled type into variable v
1422       */
1423   static bool get( Eldbus_Message_Iter* iter, std::vector< A >& v )
1424   {
1425     Eldbus_Message_Iter* s;
1426     v.clear();
1427     if( !eldbus_message_iter_get_and_next( iter, 'a', &s ) )
1428       return false;
1429     A a;
1430     while( signature< A >::get( s, a ) )
1431       v.push_back( std::move( a ) );
1432
1433     return true;
1434   }
1435 };
1436
1437 /**
1438      * @brief Signature class for marshalling std::array template type
1439      *
1440      * This marshals container's content as DBUS a ascii character type code.
1441      */
1442 template < typename A, size_t N >
1443 struct signature< std::array< A, N > >
1444 {
1445   /**
1446       * @brief Returns name of type marshalled, for informative purposes
1447       */
1448   static std::string name()
1449   {
1450     return "array<" + signature< A >::name() + ", " + std::to_string( N ) + ">";
1451   }
1452   /**
1453       * @brief Returns DBUS' signature of type marshalled
1454       */
1455   static std::string sig()
1456   {
1457     return "a" + signature< A >::sig();
1458   }
1459   /**
1460       * @brief Marshals value v as marshalled type into message
1461       */
1462   static void set( Eldbus_Message_Iter* iter, const std::array< A, N >& v )
1463   {
1464     auto lst = eldbus_message_iter_container_new( iter, 'a', signature< A >::sig().c_str() );
1465     assert( lst );
1466     for( auto& a : v )
1467     {
1468       signature< A >::set( lst, a );
1469     }
1470     eldbus_message_iter_container_close( iter, lst );
1471   }
1472   /**
1473       * @brief Marshals value from marshalled type into variable v
1474       */
1475   static bool get( Eldbus_Message_Iter* iter, std::array< A, N >& v )
1476   {
1477     Eldbus_Message_Iter* s;
1478     if( !eldbus_message_iter_get_and_next( iter, 'a', &s ) )
1479       return false;
1480     for( auto& a : v )
1481     {
1482       if( !signature< A >::get( s, a ) )
1483         return false;
1484     }
1485     return true;
1486   }
1487 };
1488
1489 /**
1490      * @brief Signature class for marshalling EldbusVariant type
1491      *
1492      * This marshals variant's content as DBUS v ascii character type code.
1493      */
1494 template < typename A >
1495 struct signature< EldbusVariant< A > >
1496 {
1497   /**
1498       * @brief Returns name of type marshalled, for informative purposes
1499       */
1500   static std::string name()
1501   {
1502     return "variant<" + signature< A >::name() + ">";
1503   }
1504   /**
1505       * @brief Returns DBUS' signature of type marshalled
1506       */
1507   static std::string sig()
1508   {
1509     return "v";
1510   }
1511   /**
1512       * @brief Marshals value v as marshalled type into message
1513       */
1514   static void set( Eldbus_Message_Iter* iter, const EldbusVariant< A >& v )
1515   {
1516     set( iter, v.value );
1517   }
1518   /**
1519       * @brief Marshals value v as marshalled type into message
1520       */
1521   static void set( Eldbus_Message_Iter* iter, const A& v )
1522   {
1523     auto var = eldbus_message_iter_container_new( iter, 'v', signature< A >::sig().c_str() );
1524     signature< A >::set( var, v );
1525     eldbus_message_iter_container_close( iter, var );
1526   }
1527   /**
1528       * @brief Marshals value from marshalled type into variable v
1529       */
1530   static bool get( Eldbus_Message_Iter* iter, EldbusVariant< A >& v )
1531   {
1532     Eldbus_Message_Iter* s;
1533     if( !eldbus_message_iter_get_and_next( iter, 'v', &s ) )
1534       return false;
1535     return signature< A >::get( s, v.value );
1536   }
1537 };
1538 /**
1539      * @brief Signature class for marshalling std::unordered_map template type
1540      *
1541      * This marshals container's content as DBUS {} ascii character type code.
1542      * Note, that library doesnt check, if the key is basic type, as DBUS
1543      * specification mandates.
1544      * User can always exchange std::unordered_map for std::map and the reverse.
1545      * User can receive such values as std::vector of std::pair<key, value> values.
1546      * Order of such values is unspecified.
1547      */
1548 template < typename A, typename B >
1549 struct signature< std::unordered_map< A, B > >
1550 {
1551   /**
1552       * @brief Returns name of type marshalled, for informative purposes
1553       */
1554   static std::string name()
1555   {
1556     return "unordered_map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
1557   }
1558   /**
1559       * @brief Returns DBUS' signature of type marshalled
1560       */
1561   static std::string sig()
1562   {
1563     return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
1564   }
1565   /**
1566       * @brief Marshals value v as marshalled type into message
1567       */
1568   static void set( Eldbus_Message_Iter* iter, const std::unordered_map< A, B >& v )
1569   {
1570     auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
1571     auto lst = eldbus_message_iter_container_new( iter, 'a', sig.c_str() );
1572     assert( lst );
1573     for( auto& a : v )
1574     {
1575       signature< std::pair< A, B > >::set( lst, a, true );
1576     }
1577     eldbus_message_iter_container_close( iter, lst );
1578   }
1579   /**
1580       * @brief Marshals value from marshalled type into variable v
1581       */
1582   static bool get( Eldbus_Message_Iter* iter, std::unordered_map< A, B >& v )
1583   {
1584     Eldbus_Message_Iter* s;
1585     v.clear();
1586     if( !eldbus_message_iter_get_and_next( iter, 'a', &s ) )
1587       return false;
1588     std::pair< A, B > a;
1589     while( signature< std::pair< A, B > >::get( s, a ) )
1590       v.insert( std::move( a ) );
1591     return true;
1592   }
1593 };
1594 /**
1595      * @brief Signature class for marshalling std::unordered_map template type
1596      *
1597      * This marshals container's content as DBUS {} ascii character type code.
1598      * Note, that library doesnt check, if the key is basic type, as DBUS
1599      * specification mandates.
1600      * User can always exchange std::unordered_map for std::map and the reverse.
1601      * User can receive such values as std::vector of std::pair<key, value> values.
1602      * Order of such values is unspecified.
1603      */
1604 template < typename A, typename B >
1605 struct signature< std::map< A, B > >
1606 {
1607   /**
1608       * @brief Returns name of type marshalled, for informative purposes
1609       */
1610   static std::string name()
1611   {
1612     return "map<" + signature< A >::name() + ", " + signature< B >::name() + ">";
1613   }
1614   /**
1615       * @brief Returns DBUS' signature of type marshalled
1616       */
1617   static std::string sig()
1618   {
1619     return "a{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
1620   }
1621   /**
1622       * @brief Marshals value v as marshalled type into message
1623       */
1624   static void set( Eldbus_Message_Iter* iter, const std::map< A, B >& v )
1625   {
1626     auto sig = "{" + signature_tuple_helper< 0, 2, A, B >::sig() + "}";
1627     auto lst = eldbus_message_iter_container_new( iter, 'a', sig.c_str() );
1628     assert( lst );
1629     for( auto& a : v )
1630     {
1631       signature< std::pair< A, B > >::set( lst, a, true );
1632     }
1633     eldbus_message_iter_container_close( iter, lst );
1634   }
1635   /**
1636       * @brief Marshals value from marshalled type into variable v
1637       */
1638   static bool get( Eldbus_Message_Iter* iter, std::map< A, B >& v )
1639   {
1640     Eldbus_Message_Iter* s;
1641     if( !eldbus_message_iter_get_and_next( iter, 'a', &s ) )
1642       return false;
1643     std::pair< A, B > a;
1644     while( signature< std::pair< A, B > >::get( s, a ) )
1645       v.insert( std::move( a ) );
1646     return true;
1647   }
1648 };
1649 /**
1650      * @brief Signature helper class for marshalling const reference types
1651      */
1652 template < typename A >
1653 struct signature< const A& >
1654 {
1655   /**
1656       * @brief Returns name of type marshalled, for informative purposes
1657       */
1658   static std::string name()
1659   {
1660     return "const " + signature< A >::name() + "&";
1661   }
1662   /**
1663       * @brief Returns DBUS' signature of type marshalled
1664       */
1665   static std::string sig()
1666   {
1667     return signature< A >::sig();
1668   }
1669   /**
1670       * @brief Marshals value v as marshalled type into message
1671       */
1672   static void set( Eldbus_Message_Iter* iter, const A& v )
1673   {
1674     signature< A >::set( iter, v );
1675   }
1676   /**
1677       * @brief Marshals value from marshalled type into variable v
1678       */
1679   static void get( Eldbus_Message_Iter* iter, A& v )
1680   {
1681     signature< A >::get( iter, v );
1682   }
1683 };
1684 /**
1685      * @brief Signature helper class for marshalling reference types
1686      */
1687 template < typename A >
1688 struct signature< A& >
1689 {
1690   /**
1691       * @brief Returns name of type marshalled, for informative purposes
1692       */
1693   static std::string name()
1694   {
1695     return signature< A >::name() + "&";
1696   }
1697   /**
1698       * @brief Returns DBUS' signature of type marshalled
1699       */
1700   static std::string sig()
1701   {
1702     return signature< A >::sig();
1703   }
1704   /**
1705       * @brief Marshals value v as marshalled type into message
1706       */
1707   static void set( Eldbus_Message_Iter* iter, const A& v )
1708   {
1709     signature< A >::set( iter, v );
1710   }
1711   /**
1712       * @brief Marshals value from marshalled type into variable v
1713       */
1714   static void get( Eldbus_Message_Iter* iter, A& v )
1715   {
1716     signature< A >::get( iter, v );
1717   }
1718 };
1719 /**
1720      * @brief Signature helper class for marshalling const types
1721      */
1722 template < typename A >
1723 struct signature< const A >
1724 {
1725   /**
1726       * @brief Returns name of type marshalled, for informative purposes
1727       */
1728   static std::string name()
1729   {
1730     return "const " + signature< A >::name();
1731   }
1732   /**
1733       * @brief Returns DBUS' signature of type marshalled
1734       */
1735   static std::string sig()
1736   {
1737     return signature< A >::sig();
1738   }
1739   /**
1740       * @brief Marshals value v as marshalled type into message
1741       */
1742   static void set( Eldbus_Message_Iter* iter, const A& v )
1743   {
1744     signature< A >::set( iter, v );
1745   }
1746   /**
1747       * @brief Marshals value from marshalled type into variable v
1748       */
1749   static void get( Eldbus_Message_Iter* iter, A& v )
1750   {
1751     signature< A >::get( iter, v );
1752   }
1753 };
1754 // /**
1755 //  * @brief Signature helper class for marshalling AT-SPI Accessible pointer values
1756 //  *
1757 //  * In AT-SPI specification those values are mandated to be marshalled as struct (so)
1758 //  * where o is object (exactly as string, but with different ascii
1759 //  * character code.
1760 //  */
1761 // template <> struct signature<std::shared_ptr<AtspiAccessible>> {
1762 //  using subtype = std::pair<std::string, std::string>;
1763
1764 //  /**
1765 //  * @brief Returns name of type marshalled, for informative purposes
1766 //  */
1767 //  static std::string name()
1768 //  {
1769 //    return "AtspiAccessiblePtr";
1770 //  }
1771 //  /**
1772 //  * @brief Returns DBUS' signature of type marshalled
1773 //  */
1774 //  static std::string sig()
1775 //  {
1776 //    return "(so)";
1777 //  }
1778 //  /**
1779 //  * @brief Marshals value v as marshalled type into message
1780 //  */
1781 //  static void set(Eldbus_Message_Iter *iter, const std::shared_ptr<AtspiAccessible> &v)
1782 //  {
1783 //    const auto prefixPath = "/org/a11y/atspi/accessible/";
1784 //    const auto nullPath = "/org/a11y/atspi/null";
1785
1786 //    if (v) {
1787 //      auto bus = atspi_accessible_get_bus_name(v.get(), NULL);
1788 //      auto path = atspi_accessible_get_path(v.get(), NULL);
1789 //      signature<subtype>::set(iter, { bus, std::string{prefixPath} + path });
1790 //      g_free(path);
1791 //      g_free(bus);
1792 //    } else {
1793 //      signature<subtype>::set(iter, { {}, std::string{nullPath} });
1794 //    }
1795 //  }
1796 //  /**
1797 //  * @brief Marshals value from marshalled type into variable v
1798 //  */
1799 //  static bool get(Eldbus_Message_Iter *iter, std::shared_ptr<AtspiAccessible> &v);
1800 // };
1801 /// \cond
1802 struct CallId
1803 {
1804   friend class ::DBus::DBusServer;
1805   friend class ::DBus::DBusClient;
1806   friend class ::DBus::DBusInterfaceDescription;
1807   static std::atomic< unsigned int > LastId;
1808   unsigned int id = ++LastId;
1809 };
1810 template < typename ValueType >
1811 ValueType unpackValues( CallId callId, const Eldbus_Message* msg )
1812 {
1813   auto iter = eldbus_message_iter_get( msg );
1814   ValueType r;
1815
1816   if( iter )
1817   {
1818     if( !signature< ValueType >::get( iter, r ) )
1819     {
1820       DBUS_DEBUG( "ValueType is %s", signature< ValueType >::name().c_str() );
1821       r = Error{"call " + std::to_string( callId.id ) + ": failed to unpack values, got signature '" +
1822                 eldbus_message_signature_get( msg ) + "', expected '" + signature< ValueType >::sig() + "'"};
1823     }
1824   }
1825   else
1826   {
1827     r = Error{"call " + std::to_string( callId.id ) + ": failed to get iterator"};
1828   }
1829   return r;
1830 }
1831 inline void packValues_helper( Eldbus_Message_Iter* iter ) {}
1832 template < typename A, typename... ARGS >
1833 void packValues_helper( Eldbus_Message_Iter* iter, A&& a, ARGS&&... r )
1834 {
1835   signature< A >::set( iter, std::forward< A >( a ) );
1836   packValues_helper( iter, std::forward< ARGS >( r )... );
1837 }
1838 template < typename... ARGS >
1839 void packValues( CallId callId, Eldbus_Message* msg, ARGS&&... r )
1840 {
1841   auto iter = eldbus_message_iter_get( msg );
1842   packValues_helper( iter, std::forward< ARGS >( r )... );
1843 }
1844
1845 template < typename >
1846 struct ReturnType;
1847 template < typename R, typename... ARGS >
1848 struct ReturnType< R( ARGS... ) >
1849 {
1850   using type = R;
1851 };
1852 template < typename R, typename... ARGS >
1853 struct ReturnType< std::function< R( ARGS... ) > >
1854 {
1855   using type = R;
1856 };
1857 template < int... >
1858 struct sequence
1859 {
1860 };
1861 template < int N, int... S >
1862 struct sequence_gen : sequence_gen< N - 1, N - 1, S... >
1863 {
1864 };
1865 template < int... S >
1866 struct sequence_gen< 0, S... >
1867 {
1868   typedef sequence< S... > type;
1869 };
1870 template < typename C, typename... ARGS >
1871 struct apply_helper
1872 {
1873   const std::function< C >& c;
1874   const std::tuple< ARGS... >& args;
1875
1876   template < int... S >
1877   auto apply_2( sequence< S... > ) const -> decltype( c( std::get< S >( args )... ) )
1878   {
1879     return c( std::get< S >( args )... );
1880   }
1881   auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
1882   {
1883     return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
1884   }
1885 };
1886 template < typename C, typename A, typename... ARGS >
1887 struct apply_helper_2
1888 {
1889   const std::function< C >& c;
1890   const A& a;
1891   const std::tuple< ARGS... >& args;
1892
1893   template < int... S >
1894   auto apply_2( sequence< S... > ) const -> decltype( c( a, std::get< S >( args )... ) )
1895   {
1896     return c( a, std::get< S >( args )... );
1897   }
1898   auto apply_1() const -> decltype( apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() ) )
1899   {
1900     return apply_2( typename sequence_gen< sizeof...( ARGS ) >::type() );
1901   }
1902 };
1903 template < typename C, typename... ARGS >
1904 auto apply( const std::function< C >& c, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
1905 {
1906   apply_helper< C, ARGS... > ah{c, args};
1907   return ah.apply_1();
1908 }
1909 template < typename C, typename D, typename... ARGS >
1910 auto apply( const std::function< C >& c, const D& d, const std::tuple< ARGS... >& args ) -> typename ReturnType< C >::type
1911 {
1912   apply_helper_2< C, D, ARGS... > ah{c, d, args};
1913   return ah.apply_1();
1914 }
1915
1916 struct EldbusProxyBase
1917 {
1918   EldbusProxyBase()
1919   {
1920     eldbus_init();
1921   }
1922   ~EldbusProxyBase()
1923   {
1924     eldbus_shutdown();
1925   }
1926 };
1927
1928 constexpr static int ELDBUS_CALL_TIMEOUT = 1000;
1929
1930 struct ConnectionState
1931 {
1932   std::shared_ptr< DBus::EldbusConnection > connection;
1933   EldbusObjectCallbackHandle object;
1934   EldbusProxyHandle proxy;
1935   EldbusProxyHandle propertiesProxy;
1936 };
1937 using CallAsyncDataType = std::tuple< CallId, std::function< void( const Eldbus_Message* ) > >;
1938
1939 static void callAsyncCb( void* data, const Eldbus_Message* msg, Eldbus_Pending* pending )
1940 {
1941   auto d = static_cast< CallAsyncDataType* >( data );
1942   DBUS_DEBUG( "call %d: got reply", std::get< 0 >( *d ).id );
1943   std::get< 1 > ( *d )( msg );
1944 }
1945 static void pendingFreeCb( void* data, const void* )
1946 {
1947   auto d = static_cast< CallAsyncDataType* >( data );
1948   DBUS_DEBUG( "call %d: deleting", std::get< 0 >( *d ).id );
1949   delete d;
1950 }
1951 template < typename RETTYPE, typename... ARGS >
1952 RETTYPE call( CallId callId, ConnectionState& connectionState, bool property, const std::string& funcName, const ARGS&... args )
1953 {
1954   auto proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
1955   if( !proxy )
1956   {
1957     DBUS_DEBUG( "call %d: not initialized", callId.id );
1958     return Error{"not initialized"};
1959   }
1960
1961   DBUS_DEBUG( "call %d: calling '%s'", callId.id, funcName.c_str() );
1962   EldbusMessageCallbackHandle msg{eldbus_proxy_method_call_new( proxy.get(), funcName.c_str() )};
1963   if( !msg )
1964   {
1965     DBUS_DEBUG( "call %d: failed", callId.id );
1966     return Error{"failed to create message"};
1967   }
1968
1969   detail::packValues( callId, msg.get(), args... );
1970   auto replyRawPtr = eldbus_proxy_send_and_block( proxy.get(), msg.release(), ELDBUS_CALL_TIMEOUT );
1971   EldbusMessageCallbackHandle reply{replyRawPtr};
1972   DBUS_DEBUG( "call %d: calling '%s' done", callId.id, funcName.c_str() );
1973   if( !reply )
1974   {
1975     DBUS_DEBUG( "call %d: failed", callId.id );
1976     return Error{"eldbus returned null as reply"};
1977   }
1978   const char *errname, *errmsg;
1979   if( eldbus_message_error_get( reply.get(), &errname, &errmsg ) )
1980   {
1981     DBUS_DEBUG( "call %d: %s: %s", callId.id, errname, errmsg );
1982     return Error{std::string( errname ) + ": " + errmsg};
1983   }
1984   DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id, eldbus_message_signature_get( reply.get() ) );
1985   return detail::unpackValues< RETTYPE >( callId, reply.get() );
1986 }
1987
1988 template < typename RETTYPE, typename... ARGS >
1989 void asyncCall( CallId callId, ConnectionState connectionState,
1990                 bool property, const std::string& funcName,
1991                 std::function< void( RETTYPE ) > callback, const ARGS&... args )
1992 {
1993   auto proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
1994   if( !proxy )
1995   {
1996     DBUS_DEBUG( "call %d: not initialized", callId.id );
1997     callback( Error{"not initialized"} );
1998     return;
1999   }
2000
2001   EldbusMessageCallbackHandle msg{eldbus_proxy_method_call_new( proxy.get(), funcName.c_str() )};
2002   if( !msg )
2003   {
2004     DBUS_DEBUG( "call %d: failed", callId.id );
2005     callback( Error{"failed to create message"} );
2006     return;
2007   }
2008
2009   auto cbData = new CallAsyncDataType{callId, [callback, callId, proxy]( const Eldbus_Message* reply ) {
2010                                         DBUS_DEBUG( "call %d: calling done", callId.id );
2011                                         if( !reply )
2012                                         {
2013                                           DBUS_DEBUG( "call %d: failed", callId.id );
2014                                           callback( Error{"eldbus returned null as reply"} );
2015                                         }
2016                                         else
2017                                         {
2018                                           const char *errname, *errmsg;
2019                                           if( eldbus_message_error_get( reply, &errname, &errmsg ) )
2020                                           {
2021                                             DBUS_DEBUG( "call %d: %s: %s", callId.id, errname, errmsg );
2022                                             callback( Error{std::string( errname ) + ": " + errmsg} );
2023                                           }
2024                                           else
2025                                           {
2026                                             DBUS_DEBUG( "call %d: got reply with signature '%s'", callId.id, eldbus_message_signature_get( reply ) );
2027                                             callback( detail::unpackValues< RETTYPE >( callId, reply ) );
2028                                           }
2029                                         }
2030                                       }};
2031   detail::packValues( callId, msg.get(), args... );
2032   auto pending = eldbus_proxy_send( proxy.get(), msg.release(), callAsyncCb, cbData, ELDBUS_CALL_TIMEOUT );
2033   if( pending )
2034   {
2035     eldbus_pending_free_cb_add( pending, pendingFreeCb, cbData );
2036     DBUS_DEBUG( "call %d: call sent", callId.id );
2037   }
2038   else
2039   {
2040     DBUS_DEBUG( "call %d: failed to send call", callId.id );
2041     callback( Error{"failed to send call"} );
2042   }
2043 }
2044 inline void displayDebugCallInfo( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
2045 {
2046   DBUS_DEBUG( "call %d: %s iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
2047 }
2048 inline void displayDebugCallInfoSignal( CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName )
2049 {
2050   DBUS_DEBUG( "call %d: %s signal iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str() );
2051 }
2052 inline void displayDebugCallInfoProperty( CallId callId, const std::string& funcName, std::string info, const std::string& interfaceName,
2053                                           const std::string& propertyName )
2054 {
2055   DBUS_DEBUG( "call %d: %s iname = %s pname = %s", callId.id, info.c_str(), interfaceName.c_str(), propertyName.c_str() );
2056 }
2057
2058 class StringStorage
2059 {
2060   struct char_ptr_deleter
2061   {
2062     void operator()( char* p )
2063     {
2064       free( p );
2065     }
2066   };
2067   std::vector< std::unique_ptr< char, char_ptr_deleter > > storage;
2068
2069 public:
2070   const char* add( const char* txt )
2071   {
2072     auto ptr = strdup( txt );
2073     storage.push_back( std::unique_ptr< char, char_ptr_deleter >( ptr ) );
2074     return storage.back().get();
2075   }
2076   const char* add( const std::string& txt )
2077   {
2078     return add( txt.c_str() );
2079   }
2080 };
2081 template < typename A, typename... ARGS >
2082 struct EldbusArgGenerator_Helper
2083 {
2084   static void add( std::vector< Eldbus_Arg_Info >& r, StringStorage& strings )
2085   {
2086     auto s = r.size();
2087     auto sig = signature< A >::sig();
2088     assert( !sig.empty() );
2089     auto name = "p" + std::to_string( s + 1 );
2090     r.push_back( Eldbus_Arg_Info{strings.add( sig ), strings.add( name )} );
2091     EldbusArgGenerator_Helper< ARGS... >::add( r, strings );
2092   }
2093 };
2094 template <>
2095 struct EldbusArgGenerator_Helper< void >
2096 {
2097   static void add( std::vector< Eldbus_Arg_Info >&, StringStorage& )
2098   {
2099   }
2100 };
2101 template <>
2102 struct EldbusArgGenerator_Helper< ValueOrError< void >, void >
2103 {
2104   static void add( std::vector< Eldbus_Arg_Info >&, StringStorage& )
2105   {
2106   }
2107 };
2108 template <>
2109 struct EldbusArgGenerator_Helper< ValueOrError<>, void >
2110 {
2111   static void add( std::vector< Eldbus_Arg_Info >&, StringStorage& )
2112   {
2113   }
2114 };
2115 template < typename... ARGS >
2116 struct EldbusArgGenerator_Helper< std::tuple< ARGS... > >
2117 {
2118   static void add( std::vector< Eldbus_Arg_Info >& r, StringStorage& strings )
2119   {
2120     EldbusArgGenerator_Helper< ARGS..., void >::add( r, strings );
2121   }
2122 };
2123 template < typename RetType >
2124 struct dbus_interface_return_type_traits
2125 {
2126   using type = ValueOrError< RetType >;
2127 };
2128 template < typename... ARGS >
2129 struct dbus_interface_return_type_traits< ValueOrError< ARGS... > >
2130 {
2131   using type = ValueOrError< ARGS... >;
2132 };
2133 template < typename T >
2134 struct dbus_interface_traits;
2135 template < typename RetType, typename... ARGS >
2136 struct dbus_interface_traits< RetType( ARGS... ) >
2137 {
2138   using Ret = typename dbus_interface_return_type_traits< RetType >::type;
2139   using SyncCB = std::function< Ret( ARGS... ) >;
2140   using AsyncCB = std::function< void( std::function< void( Ret ) >, ARGS... ) >;
2141   using VEArgs = ValueOrError< ARGS... >;
2142 };
2143 template < typename T >
2144 struct EldbusArgGenerator_Args;
2145 template < typename RetType, typename... ARGS >
2146 struct EldbusArgGenerator_Args< RetType( ARGS... ) >
2147 {
2148   static std::string name()
2149   {
2150     return signature_tuple_helper< 0, sizeof...( ARGS ), ARGS... >::name();
2151   }
2152   static std::vector< Eldbus_Arg_Info > get( StringStorage& strings )
2153   {
2154     std::vector< Eldbus_Arg_Info > tmp;
2155     EldbusArgGenerator_Helper< ARGS..., void >::add( tmp, strings );
2156     tmp.push_back( {nullptr, nullptr} );
2157     return tmp;
2158   }
2159 };
2160 template < typename T >
2161 struct EldbusArgGenerator_ReturnType;
2162 template < typename RetType, typename... ARGS >
2163 struct EldbusArgGenerator_ReturnType< RetType( ARGS... ) >
2164 {
2165   static std::string name()
2166   {
2167     return signature< RetType >::name();
2168   }
2169   static std::vector< Eldbus_Arg_Info > get( StringStorage& strings )
2170   {
2171     std::vector< Eldbus_Arg_Info > tmp;
2172     EldbusArgGenerator_Helper< RetType, void >::add( tmp, strings );
2173     tmp.push_back( {nullptr, nullptr} );
2174     return tmp;
2175   }
2176 };
2177 template < typename T >
2178 struct EldbusArgGenerator_ReturnType;
2179 template < typename... ARGS >
2180 struct EldbusArgGenerator_ReturnType< void( ARGS... ) >
2181 {
2182   static std::string name()
2183   {
2184     return "";
2185   }
2186   static std::vector< Eldbus_Arg_Info > get( StringStorage& strings )
2187   {
2188     std::vector< Eldbus_Arg_Info > tmp;
2189     tmp.push_back( {nullptr, nullptr} );
2190     return tmp;
2191   }
2192 };
2193 /// \endcond
2194 }
2195
2196 /**
2197   * @brief Enumeration determining, which DBUS session user wants to connect to.
2198   */
2199 enum class ConnectionType
2200 {
2201   SYSTEM,
2202   SESSION
2203 };
2204
2205 /**
2206   * @brief Class representing client's end of DBUS connection
2207   *
2208   * Allows calling (synchronous and asynchronos) methods on selected interface
2209   * Allows (synchronous and asynchronos) setting / getting properties.
2210   * Allows registering signals.
2211   */
2212 class DBusClient : private detail::EldbusProxyBase
2213 {
2214   /// \cond
2215   struct ConnectionInfo
2216   {
2217     std::string interfaceName, busName, pathName;
2218     void emit( const char* member, DBusActionType type )
2219     {
2220       detail::emitNotification( busName.c_str(), pathName.c_str(), interfaceName.c_str(), member, type );
2221     }
2222   };
2223   /// \endcond
2224 public:
2225   /**
2226     * @brief Default constructor, creates non-connected object.
2227     */
2228   DBusClient() = default;
2229   /**
2230     * @brief Connects to dbus choosen by tp, using given arguments
2231     *
2232     * @param bus_name name of the bus to connect to
2233     * @param path_name object's path
2234     * @param interface_name interface name
2235     */
2236   DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
2237               ConnectionType tp );
2238   /**
2239     * @brief Connects to dbus using connection conn
2240     *
2241     * @param bus_name name of the bus to connect to
2242     * @param path_name object's path
2243     * @param interface_name interface name
2244     * @param conn connection object from getDBusConnectionByType call
2245     */
2246   DBusClient( std::string busName_, std::string pathName_, std::string interfaceName_,
2247               const std::shared_ptr< DBus::EldbusConnection >& conn = {} );
2248   /**
2249     * @brief Destructor object.
2250     *
2251     * All signals added will be disconnected.
2252     * All asynchronous calls will be cancelled, their callback's will be called
2253     * with failure message.
2254     */
2255   ~DBusClient() = default;
2256   DBusClient( const DBusClient& ) = delete;
2257   DBusClient( DBusClient&& ) = default;
2258
2259   DBusClient& operator=( DBusClient&& ) = default;
2260   DBusClient& operator=( const DBusClient& ) = delete;
2261
2262   /**
2263     * @brief bool operator
2264     *
2265     * Returns true, if object is connected to DBUS
2266     */
2267   explicit operator bool() const
2268   {
2269     return bool( connectionState.proxy );
2270   }
2271
2272   /**
2273     * @brief Helper class for calling a method
2274     *
2275     * Template type T defines both arguments sent to the method
2276     * and expected values. Receiving different values will be reported as
2277     * error. For example:
2278     * \code{.cpp} Method<int(float, float)> \endcode
2279     * defines method, which takes two arguments (two floats) and return
2280     * single value of type int.
2281     */
2282   template < typename T >
2283   struct Method
2284   {
2285     /// \cond
2286     using RetType = typename detail::dbus_interface_traits< T >::Ret;
2287     detail::ConnectionState connectionState;
2288     std::string funcName;
2289     std::string info;
2290     std::shared_ptr< ConnectionInfo > connectionInfo;
2291     /// \endcond
2292
2293     /**
2294        * @brief Executes synchronous call on DBUS's method
2295        *
2296        * The function returns ValueOrError<...> object, which
2297        * contains either received values or error message.
2298        *
2299        * @param args arguments to pass to the method
2300        */
2301     template < typename... ARGS >
2302     RetType call( const ARGS&... args )
2303     {
2304       detail::CallId callId;
2305       detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
2306       return detail::call< RetType >( callId, connectionState, false, funcName, args... );
2307     }
2308
2309     /**
2310        * @brief Executes asynchronous call on DBUS's method
2311        *
2312        * The function calls callback with either received values or error message.
2313        *
2314        * @param callback callback functor, which will be called with return value(s) or error message
2315        * @param args arguments to pass to the method
2316        */
2317     template < typename... ARGS >
2318     void asyncCall( std::function< void( RetType ) > callback, const ARGS&... args )
2319     {
2320       detail::CallId callId;
2321       detail::displayDebugCallInfo( callId, funcName, info, connectionInfo->interfaceName );
2322       auto connectionState = this->connectionState;
2323       detail::asyncCall< RetType >( callId, connectionState, false, funcName, std::move( callback ), args... );
2324     }
2325   };
2326
2327   /**
2328     * @brief Helper class for calling a property
2329     *
2330     * Template type T defines type of the value hidden under property.
2331     * Note, that library automatically wraps both sent and received value into
2332     * DBUS's wrapper type.
2333     */
2334   template < typename T >
2335   struct Property
2336   {
2337     /// \cond
2338     using RetType = typename detail::dbus_interface_return_type_traits< T >::type;
2339     using VariantRetType = typename detail::dbus_interface_return_type_traits< EldbusVariant< T > >::type;
2340     detail::ConnectionState connectionState;
2341     std::string propName;
2342     std::string info;
2343     std::shared_ptr< ConnectionInfo > connectionInfo;
2344     /// \endcond
2345
2346     /**
2347       * @brief executes synchronous get on property
2348       *
2349       * The function returns ValueOrError<...> object, which
2350       * contains either received values or error message.
2351       */
2352     RetType get()
2353     {
2354       connectionInfo->emit( propName.c_str(), DBusActionType::GETTER_CALL );
2355       detail::CallId callId;
2356       detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
2357       auto z = detail::call< VariantRetType >( callId, connectionState, true, "Get", connectionInfo->interfaceName, propName );
2358       if( !z )
2359         return z.getError();
2360       return {std::get< 0 >( z.getValues() ).value};
2361     }
2362
2363     /**
2364       * @brief executes asynchronous get on property
2365       *
2366       * The function calls callback with either received values or error message.
2367       *
2368       * @param callback callback functor, which will be called with return value(s) or error message
2369       */
2370     void asyncGet( std::function< void( RetType ) > callback )
2371     {
2372       connectionInfo->emit( propName.c_str(), DBusActionType::GETTER_CALL );
2373       detail::CallId callId;
2374       detail::displayDebugCallInfoProperty( callId, "Get", info, connectionInfo->interfaceName, propName );
2375       auto connectionState = this->connectionState;
2376       auto cc = [callback]( VariantRetType reply ) {
2377         if( reply )
2378           callback( std::move( std::get< 0 >( reply.getValues() ).value ) );
2379         else
2380           callback( reply.getError() );
2381       };
2382       detail::asyncCall< VariantRetType >( callId, connectionState, true, "Get", std::move( cc ), connectionInfo->interfaceName, propName );
2383     }
2384
2385     /**
2386       * @brief executes synchronous set on property
2387       *
2388       * The function returns ValueOrError<void> object, with
2389       * possible error message.
2390       */
2391     ValueOrError< void > set( const T& r )
2392     {
2393       connectionInfo->emit( propName.c_str(), DBusActionType::SETTER_CALL );
2394       detail::CallId callId;
2395       detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
2396       EldbusVariant< T > variantValue{std::move( r )};
2397       return detail::call< ValueOrError< void > >( callId, connectionState, true, "Set", connectionInfo->interfaceName, propName, variantValue );
2398     }
2399
2400     /**
2401       * @brief executes asynchronous get on property
2402       *
2403       * The function calls callback with either received values or error message.
2404       *
2405       * @param callback callback functor, which will be called with return value(s) or error message
2406       */
2407     void asyncSet( std::function< void( ValueOrError< void > ) > callback, const T& r )
2408     {
2409       connectionInfo->emit( propName.c_str(), DBusActionType::SETTER_CALL );
2410       detail::CallId callId;
2411       detail::displayDebugCallInfoProperty( callId, "Set", info, connectionInfo->interfaceName, propName );
2412       EldbusVariant< T > variantValue{std::move( r )};
2413       detail::asyncCall< ValueOrError< void > >( callId, connectionState, true, "Set", std::move( callback ), connectionInfo->interfaceName, propName, variantValue );
2414     }
2415   };
2416
2417   /**
2418     * @brief Constructs Property<...> object for calling properties
2419     *
2420     * The function constructs and returns proxy object for calling property.
2421     *
2422     * @param propName property name to set and / or query
2423     */
2424   template < typename PropertyType >
2425   Property< PropertyType > property( std::string propName )
2426   {
2427     return Property< PropertyType >{connectionState, std::move( propName ), info, connectionInfo};
2428   }
2429
2430   /**
2431     * @brief Constructs Method<...> object for calling methods
2432     *
2433     * The function constructs and returns proxy object for calling method.
2434     *
2435     * @param funcName function name to call
2436     */
2437   template < typename MethodType >
2438   Method< MethodType > method( std::string funcName )
2439   {
2440     return Method< MethodType >{connectionState, std::move( funcName ), info, connectionInfo};
2441   }
2442
2443   /**
2444      * @brief Registers notification callback, when property has changed
2445      *
2446      * The callback will be called with new value, when property's value has changed.
2447      * Note, that template type V must match expected type, otherwise undefined behavior will occur,
2448      * there's no check for this.
2449      */
2450   template < typename V >
2451   void addPropertyChangedEvent( std::string propertyName, std::function< void( V ) > callback )
2452   {
2453     detail::CallId callId;
2454     detail::displayDebugCallInfoSignal( callId, propertyName, info, connectionInfo->interfaceName );
2455     DBUS_DEBUG( "call %d: adding property", callId.id );
2456     auto cS = this->connectionState;
2457     auto cI = this->connectionInfo;
2458     auto callbackLambdaPtr = new std::function< void( Eldbus_Proxy_Event_Property_Changed* ) >;
2459     *callbackLambdaPtr = [callId, cS, callback, propertyName, cI]( Eldbus_Proxy_Event_Property_Changed* ev ) {
2460       const char* ifc = eldbus_proxy_interface_get( ev->proxy );
2461       DBUS_DEBUG( "call %d: property changed iname = %s pname = %s (name %s iface %s)",
2462                   callId.id, cI->interfaceName.c_str(), propertyName.c_str(), ev->name, ifc );
2463       V val = 0;
2464       if( ev->name && ev->name == propertyName && ifc && cI->interfaceName == ifc )
2465       {
2466         if( !eina_value_get( ev->value, &val ) )
2467         {
2468           DBUS_DEBUG( "unable to get property's value" );
2469           return;
2470         }
2471         DBUS_DEBUG( ". %d", val );
2472         callback( val );
2473         DBUS_DEBUG( "." );
2474       }
2475       DBUS_DEBUG( "." );
2476     };
2477     auto p = connectionState.proxy.get();
2478     eldbus_proxy_event_callback_add( p, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
2479                                      listenerEventChangedCallback, callbackLambdaPtr );
2480     destructors.add( [=]() {
2481       eldbus_proxy_event_callback_del( p, ELDBUS_PROXY_EVENT_PROPERTY_CHANGED,
2482                                        listenerEventChangedCallback, callbackLambdaPtr );
2483       delete callbackLambdaPtr;
2484     } );
2485   }
2486   /**
2487     * @brief Registers callback on the DBUS' signal
2488     *
2489     * The function registers callback signalName. When signal comes, callback will be called.
2490     * Callback object will exists as long as signal is registered. You can unregister signal
2491     * by destroying DBusClient object.
2492     *
2493     * @param signalName name of the signal to register
2494     * @param callback callback to call
2495     */
2496   template < typename SignalType >
2497   void addSignal( std::string signalName, std::function< SignalType > callback )
2498   {
2499     detail::CallId callId;
2500     detail::displayDebugCallInfoSignal( callId, signalName, info, connectionInfo->interfaceName );
2501     auto cS = this->connectionState;
2502     auto cI = this->connectionInfo;
2503     auto callbackLambda = [callId, cS, callback, signalName, cI]( const Eldbus_Message* msg ) -> void {
2504       const char *errname, *aux;
2505       if( eldbus_message_error_get( msg, &errname, &aux ) )
2506       {
2507         DBUS_DEBUG( "call %d: Eldbus error: %s %s", callId.id, errname, aux );
2508         return;
2509       }
2510       cI->emit( signalName.c_str(), DBusActionType::SIGNAL_RECEIVED );
2511       DBUS_DEBUG( "call %d: received signal with signature '%s'", callId.id, eldbus_message_signature_get( msg ) );
2512       using ParamsType = typename detail::dbus_interface_traits< SignalType >::VEArgs;
2513       auto params = detail::unpackValues< ParamsType >( callId, msg );
2514       if( !params )
2515       {
2516         DBUS_DEBUG( "call %d: failed: %s", callId.id, params.getError().message.c_str() );
2517         return;
2518       }
2519       try
2520       {
2521         detail::apply( callback, params.getValues() );
2522       }
2523       catch( ... )
2524       {
2525         DBUS_DEBUG( "unhandled exception" );
2526         assert( 0 );
2527       }
2528     };
2529     auto tmp = new std::function< void( const Eldbus_Message* msg ) >{std::move( callbackLambda )};
2530     auto handler = eldbus_proxy_signal_handler_add( connectionState.proxy.get(), signalName.c_str(), listenerCallback, tmp );
2531     destructors.add( [=]() {
2532       eldbus_signal_handler_del( handler );
2533       delete tmp;
2534     } );
2535   }
2536
2537 private:
2538   /// \cond
2539   detail::ConnectionState connectionState;
2540   detail::CallOnDestructionList destructors;
2541   std::string info;
2542   std::shared_ptr< ConnectionInfo > connectionInfo;
2543   void emitNotification( DBusActionType type );
2544
2545   static void listenerCallback( void* data, const Eldbus_Message* msg )
2546   {
2547     auto p = static_cast< std::function< void( const Eldbus_Message* msg ) >* >( data );
2548     ( *p )( msg );
2549   }
2550   static void listenerEventChangedCallback( void* data, Eldbus_Proxy* proxy EINA_UNUSED, void* event )
2551   {
2552     auto p = static_cast< std::function< void( Eldbus_Proxy_Event_Property_Changed* ) >* >( data );
2553     ( *p )( static_cast< Eldbus_Proxy_Event_Property_Changed* >( event ) );
2554   }
2555   /// \endcond
2556 };
2557
2558 /**
2559    * @brief Helper class describing DBUS's server interface
2560    *
2561    */
2562 class DBusInterfaceDescription
2563 {
2564   friend class DBusServer;
2565
2566 public:
2567   /// \cond
2568   struct MethodInfo
2569   {
2570     detail::CallId id;
2571     std::string memberName;
2572     std::vector< Eldbus_Arg_Info > in, out;
2573     std::function< Eldbus_Message*( const Eldbus_Message* msg ) > callback;
2574   };
2575   struct SignalInfo
2576   {
2577     detail::CallId id;
2578     std::string memberName;
2579     std::vector< Eldbus_Arg_Info > args;
2580     unsigned int uniqueId;
2581   };
2582   struct PropertyInfo
2583   {
2584     detail::CallId setterId, getterId;
2585     std::string memberName, typeSignature;
2586     std::function< ValueOrError< void >( const Eldbus_Message*src, Eldbus_Message_Iter*dst ) > getCallback, setCallback;
2587   };
2588   class SignalId
2589   {
2590     friend class ::DBus::DBusServer;
2591     friend class ::DBus::DBusClient;
2592     friend class ::DBus::DBusInterfaceDescription;
2593     detail::CallId id;
2594
2595     SignalId( detail::CallId id ) : id( id ) {}
2596
2597   public:
2598     SignalId() = default;
2599   };
2600   /// \endcond
2601
2602   /**
2603      * @brief Creates empty interface description with given name
2604      *
2605      * @param interfaceName name of the interface
2606      */
2607   DBusInterfaceDescription( std::string interfaceName );
2608
2609   /**
2610      * @brief adds new, synchronous method to the interface
2611      *
2612      * When method memberName is called on DBUS, callback functor will be called
2613      * with values received from DBUS. callback won't be called, if method was
2614      * called with invalid signature. Value returned from functor (or error message)
2615      * will be marshalled back to the caller.
2616      *
2617      * Template type T defines both arguments sent to the method
2618      * and expected values. Receiving different values will be reported as
2619      * error. For example:
2620      * \code{.cpp} Method<int(float, float)> \endcode
2621      * defines method, which takes two arguments (two floats) and return
2622      * single value of type int.
2623      *
2624      * @param memberName name of the method
2625      * @param callback functor, which will be called
2626      */
2627   template < typename T >
2628   void addMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::SyncCB callback )
2629   {
2630     detail::CallId callId;
2631     MethodInfo mi;
2632     methods.push_back( std::move( mi ) );
2633     auto& z = methods.back();
2634     z.in = detail::EldbusArgGenerator_Args< T >::get( strings );
2635     z.out = detail::EldbusArgGenerator_ReturnType< T >::get( strings );
2636     z.memberName = memberName;
2637     DBUS_DEBUG( "call %d: method %s, in %s, out %s", callId.id, memberName.c_str(),
2638                 detail::EldbusArgGenerator_Args< T >::name().c_str(),
2639                 detail::EldbusArgGenerator_ReturnType< T >::name().c_str() );
2640     z.callback = construct< T >( callId, callback );
2641     z.id = callId;
2642   }
2643
2644   /**
2645      * @brief adds new, asynchronous method to the interface
2646      *
2647      * When method memberName is called on DBUS, callback functor will be called
2648      * with values received from DBUS. callback won't be called, if method was
2649      * called with invalid signature. callback will called with reply callback functor.
2650      * Reply callback functor must be called with reply value, when it's ready.
2651      * It's safe to ignore calling reply callback, but some resources might be kept
2652      * as long as either reply callback exists or reply timeout hasn't yet been met.
2653      *
2654      * Template type T defines both arguments sent to the method
2655      * and expected values. Receiving different values will be reported as
2656      * error. For example:
2657      * \code{.cpp} Method<int(float, float)> \endcode
2658      * defines method, which takes two arguments (two floats) and return
2659      * single value of type int.
2660      *
2661      * @param memberName name of the method
2662      * @param callback functor, which will be called
2663      */
2664   template < typename T >
2665   void addAsyncMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::AsyncCB callback );
2666
2667   /**
2668      * @brief adds new, synchronous property to the interface
2669      *
2670      * When property memberName is called on DBUS, respective callback functor will be called
2671      * with values received from DBUS. callback won't be called, if method was
2672      * called with invalid signature. Value returned from functor (or error message)
2673      * will be marshalled back to the caller.
2674      *
2675      * Template type T defines type of the value hidden under property.
2676      * Note, that library automatically wraps both sent and received value into
2677      * DBUS's wrapper type.
2678      *
2679      * @param memberName name of the method
2680      * @param getter functor, which will be called when property is being read
2681      * @param setter functor, which will be called when property is being set
2682      */
2683   template < typename T >
2684   void addProperty( const std::string& memberName, std::function< ValueOrError< T >() > getter, std::function< ValueOrError< void >( T ) > setter )
2685   {
2686     properties.push_back( {} );
2687     auto& z = properties.back();
2688     z.memberName = memberName;
2689     z.typeSignature = detail::signature< T >::sig();
2690     if( getter )
2691     {
2692       detail::CallId getterId;
2693       z.getterId = getterId;
2694       DBUS_DEBUG( "call %d: property %s (get) type %s", getterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
2695       z.getCallback = [=]( const Eldbus_Message* src, Eldbus_Message_Iter* dst ) -> ValueOrError< void > {
2696         detail::emitNotification( eldbus_message_sender_get( src ),
2697                                   eldbus_message_path_get( src ), interfaceName.c_str(), memberName.c_str(), DBusActionType::GETTER_RESPONSE );
2698         try
2699         {
2700           auto v = detail::apply( getter, std::tuple<>{} );
2701           if( v )
2702           {
2703             detail::signature< T >::set( dst, std::get< 0 >( v.getValues() ) );
2704             DBUS_DEBUG( "call %d: success", getterId.id );
2705             return Success{};
2706           }
2707           DBUS_DEBUG( "call %d: failed: %s", getterId.id, v.getError().message.c_str() );
2708           return v.getError();
2709         }
2710         catch( std::exception& e )
2711         {
2712           return Error{std::string( "unhandled exception (" ) + e.what() + ")"};
2713         }
2714         catch( ... )
2715         {
2716           return Error{"unhandled exception"};
2717         }
2718       };
2719     }
2720     if( setter )
2721     {
2722       detail::CallId setterId;
2723       z.setterId = setterId;
2724       DBUS_DEBUG( "call %d: property %s (set) type %s", setterId.id, memberName.c_str(), detail::signature< T >::name().c_str() );
2725       z.setCallback = [=]( const Eldbus_Message* src, Eldbus_Message_Iter* src_iter ) -> ValueOrError< void > {
2726         detail::emitNotification( eldbus_message_sender_get( src ),
2727                                   eldbus_message_path_get( src ), interfaceName.c_str(), memberName.c_str(), DBusActionType::SETTER_RESPONSE );
2728         std::tuple< T > value;
2729         auto src_signature = eldbus_message_iter_signature_get( src_iter );
2730         if( detail::signature< T >::get( src_iter, std::get< 0 >( value ) ) )
2731         {
2732           try
2733           {
2734             auto v = detail::apply( setter, std::move( value ) );
2735             if( v )
2736             {
2737               DBUS_DEBUG( "call %d: success", setterId.id );
2738               return Success{};
2739             }
2740             DBUS_DEBUG( "call %d: failed: %s", setterId.id, v.getError().message.c_str() );
2741             free( src_signature );
2742             return v.getError();
2743           }
2744           catch( std::exception& e )
2745           {
2746             return Error{std::string( "unhandled exception (" ) + e.what() + ")"};
2747           }
2748           catch( ... )
2749           {
2750             return Error{"unhandled exception"};
2751           }
2752         }
2753         DBUS_DEBUG( "call %d: failed to unpack values, got signature '%s', expected '%s'", setterId.id,
2754                     src_signature, detail::signature< T >::sig().c_str() );
2755         return Error{"call " + std::to_string( setterId.id ) + ": failed to unpack values, got signature '" +
2756                      src_signature + "', expected '" + detail::signature< T >::sig() + "'"};
2757       };
2758     }
2759   }
2760
2761   /**
2762      * @brief adds new signal to the interface
2763      *
2764      * Template types ARGS defines values, which will be emited with the signal
2765      *
2766      * @param memberName name of the method
2767      */
2768   template < typename... ARGS >
2769   SignalId addSignal( const std::string& memberName )
2770   {
2771     detail::CallId callId;
2772     signals.push_back( {} );
2773     auto& z = signals.back();
2774     z.memberName = memberName;
2775     z.args = detail::EldbusArgGenerator_Args< void( ARGS... ) >::get( strings );
2776     z.id = callId;
2777     DBUS_DEBUG( "call %d: signal %s", callId.id, memberName.c_str() );
2778     return SignalId{callId};
2779   }
2780
2781 private:
2782   /// \cond
2783   std::vector< MethodInfo > methods;
2784   std::vector< PropertyInfo > properties;
2785   std::vector< SignalInfo > signals;
2786   std::string interfaceName;
2787   detail::StringStorage strings;
2788
2789   template < typename T >
2790   std::function< Eldbus_Message*( const Eldbus_Message* msg ) > construct( detail::CallId callId,
2791                                                                            typename detail::dbus_interface_traits< T >::SyncCB callback )
2792   {
2793     using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs;
2794     return [=]( const Eldbus_Message* msg ) -> Eldbus_Message* {
2795       DBUS_DEBUG( "call %d: entering", callId.id );
2796       detail::emitNotification( eldbus_message_sender_get( msg ),
2797                                 eldbus_message_path_get( msg ), interfaceName.c_str(), eldbus_message_member_get( msg ), DBusActionType::METHOD_RESPONSE );
2798       Eldbus_Message* ret = nullptr;
2799       auto args = detail::unpackValues< VEArgs >( callId, msg );
2800       if( args )
2801       {
2802         try
2803         {
2804           auto v = detail::apply( callback, std::move( args.getValues() ) );
2805           if( v )
2806           {
2807             DBUS_DEBUG( "call %d: success", callId.id );
2808             ret = eldbus_message_method_return_new( msg );
2809             packValues( callId, ret, v );
2810           }
2811           else
2812           {
2813             DBUS_DEBUG( "call %d: failed: %s", callId.id, v.getError().message.c_str() );
2814             ret = eldbus_message_error_new( msg, "org.freedesktop.DBus.Error.Failed", v.getError().message.c_str() );
2815           }
2816         }
2817         catch( std::exception& e )
2818         {
2819           auto txt = std::string( "unhandled exception (" ) + e.what() + ")";
2820           DBUS_DEBUG( "call %d: failed: %s", callId.id, txt.c_str() );
2821           ret = eldbus_message_error_new( msg, "org.freedesktop.DBus.Error.Failed", txt.c_str() );
2822         }
2823         catch( ... )
2824         {
2825           DBUS_DEBUG( "call %d: failed: %s", callId.id, "unhandled exception" );
2826           ret = eldbus_message_error_new( msg, "org.freedesktop.DBus.Error.Failed", "unhandled exception" );
2827         }
2828       }
2829       else
2830       {
2831         std::ostringstream err;
2832         err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << eldbus_message_signature_get( msg ) << "'";
2833         auto str = err.str();
2834         DBUS_DEBUG( "call %d: failed: %s", callId.id, str.c_str() );
2835         ret = eldbus_message_error_new( msg, "org.freedesktop.DBus.Error.InvalidArgs", str.c_str() );
2836       }
2837       return ret;
2838     };
2839   }
2840   /// \endcond
2841 };
2842
2843 /**
2844   * @brief Class representing server's end of DBUS connection
2845   *
2846   * Allows listening (synchronously and asynchronosly) on methods on selected interface
2847   * Allows listening (synchronously and asynchronosly) on setting / getting properties.
2848   * Allows emiting signals.
2849   */
2850 class DBusServer : private detail::EldbusProxyBase
2851 {
2852 public:
2853   /**
2854      * @brief Constructs non-connected dbus server.
2855      */
2856   DBusServer() = default;
2857
2858   /**
2859      * @brief Constructs dbus server on either system or user dbus connection.
2860      */
2861
2862   DBusServer( ConnectionType tp );
2863   /**
2864      * @brief Constructs dbus server on connection from getDBusConnectionByType
2865      */
2866
2867   DBusServer( const std::shared_ptr< DBus::EldbusConnection >& conn );
2868   /**
2869      * @brief Destructor
2870      *
2871      * Destructor will properly destroy everything. Destructor will cancel
2872      * pending replies.
2873      */
2874   ~DBusServer() = default;
2875
2876   DBusServer( const DBusServer& ) = delete;
2877   DBusServer( DBusServer&& ) = default;
2878
2879   DBusServer& operator=( DBusServer&& ) = default;
2880   DBusServer& operator=( const DBusServer& ) = delete;
2881
2882   /**
2883      * @brief Registers interface on given path name
2884      *
2885      * @param pathName path object to register interface on.
2886      * @param dscr
2887      * @param fallback
2888      */
2889   void addInterface( const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback = false );
2890
2891   /**
2892      * @brief Gets bus name of the current connection (must be connected)
2893      */
2894   std::string getBusName() const;
2895
2896   /**
2897      * @brief Returns connection object for this dbus server object
2898      *
2899      * @return connection object
2900      */
2901   std::shared_ptr< DBus::EldbusConnection > getConnection();
2902
2903   /**
2904      * @brief Emits signal
2905      *
2906      * You must pass identifier of the signal, got as result of calling DBusInterfaceDescription::addSignal.
2907      * Types of the arguments must match EXACTLY types used to call addSignal.
2908      *
2909      * @param signal identifier of the signal
2910      * @param args values to emit
2911      */
2912   template < typename... ARGS >
2913   void emit( DBusInterfaceDescription::SignalId signal, const ARGS&... args )
2914   {
2915     auto it = signalData.find( signal.id.id );
2916     if( it != signalData.end() )
2917     {
2918       auto msg = eldbus_service_signal_new( it->second.first, it->second.second );
2919       detail::packValues( signal.id, msg, args... );
2920       eldbus_service_signal_send( it->second.first, msg );
2921     }
2922     else
2923     {
2924       DBUS_DEBUG( "signal %d not found", signal.id.id );
2925     }
2926   }
2927
2928   /**
2929      * @brief Emits signal
2930      *
2931      * Emits signal based only on data passed to the function
2932      *
2933      * @param signal identifier of the signal
2934      * @param args values to emit
2935      */
2936   template < typename... ARGS >
2937   void emit2( const std::string& path, const std::string& interfaceName,
2938               const std::string& signalName, const ARGS&... args )
2939   {
2940     auto msg = eldbus_message_signal_new( path.c_str(), interfaceName.c_str(), signalName.c_str() );
2941     detail::CallId id;
2942     detail::packValues( id, msg, args... );
2943     eldbus_connection_send( connection->get(), msg, nullptr, nullptr, -1 );
2944   }
2945   /**
2946      * @brief Returns current object path, when handling call to property / method
2947      *
2948      * User can call this function from inside callback used to handle property / method calls.
2949      * It will retrieve object's path used in the call. Note, that in asynchronous handling
2950      * of those calls user need to retrieve and store the current object / current connection
2951      * as the value will change at the moment user's callback handling will exit. For example:
2952      * \code{.cpp}
2953      * DBusInterfaceDescription interface{"name"};
2954      * auto handler_later = [](std::function<void(void)> done_cb) {
2955      *   // process something later on
2956      *   DBusServer::getCurrentObjectPath(); // this will return empty string
2957      * };
2958      * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
2959      *   DBusServer::getCurrentObjectPath(); // this will current object's path
2960      *
2961      *   // do some processing later on and call done_cb, when it's done
2962      *   register_to_call_sometime_later_on(std::move(done_cb));
2963      * };
2964      * \endcode
2965      */
2966   static std::string getCurrentObjectPath();
2967
2968   /**
2969      * @brief Returns current connection object, when handling call to property / method
2970      *
2971      * User can call this function from inside callback used to handle property / method calls.
2972      * It will retrieve object's path used in the call. Note, that in asynchronous handling
2973      * of those calls user need to retrieve and store the current object / current connection
2974      * as the value will change at the moment user's callback handling will exit. For example:
2975      * \code{.cpp}
2976      * DBusInterfaceDescription interface{"name"};
2977      * auto handler_later = [](std::function<void(void)> done_cb) {
2978      *   // process something later on
2979      *   DBusServer::getCurrentObjectPath(); // this will return empty string
2980      * };
2981      * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
2982      *   DBusServer::getCurrentObjectPath(); // this will current object's path
2983      *
2984      *   // do some processing later on and call done_cb, when it's done
2985      *   register_to_call_sometime_later_on(std::move(done_cb));
2986      * };
2987      * \endcode
2988      */
2989   static std::shared_ptr< DBus::EldbusConnection > getCurrentConnection();
2990
2991 private:
2992   /// \cond
2993   std::shared_ptr< DBus::EldbusConnection > connection;
2994   detail::CallOnDestructionList destructors;
2995   std::unordered_map< unsigned int, std::pair< const Eldbus_Service_Interface*, unsigned int > > signalData;
2996   /// \endcond
2997 };
2998
2999 template < typename T >
3000 void DBusInterfaceDescription::addAsyncMethod( const std::string& memberName, typename detail::dbus_interface_traits< T >::AsyncCB callback )
3001 {
3002   detail::CallId callId;
3003   MethodInfo mi;
3004   methods.push_back( std::move( mi ) );
3005   auto& z = methods.back();
3006   z.in = detail::EldbusArgGenerator_Args< T >::get( strings );
3007   z.out = detail::EldbusArgGenerator_ReturnType< T >::get( strings );
3008   z.memberName = memberName;
3009   DBUS_DEBUG( "call %d: method %s, in %s, out %s", callId.id, memberName.c_str(),
3010               detail::EldbusArgGenerator_Args< T >::name().c_str(),
3011               detail::EldbusArgGenerator_ReturnType< T >::name().c_str() );
3012   using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs;
3013   z.callback = [=]( const Eldbus_Message* msg ) -> Eldbus_Message* {
3014     detail::emitNotification( eldbus_message_sender_get( msg ),
3015                               eldbus_message_path_get( msg ), interfaceName.c_str(), memberName.c_str(), DBusActionType::METHOD_RESPONSE );
3016     struct CallState
3017     {
3018       bool replyRunning = true;
3019       Eldbus_Message* reply = nullptr;
3020       EldbusMessageCallbackHandle message;
3021     };
3022     auto callState = std::make_shared< CallState >();
3023     callState->message.reset( eldbus_message_ref( const_cast< Eldbus_Message* >( msg ) ) );
3024     auto connection = DBusServer::getCurrentConnection();
3025     auto retCallback = [=]( typename detail::dbus_interface_traits< T >::Ret v ) {
3026       if( v )
3027       {
3028         callState->reply = eldbus_message_method_return_new( callState->message.get() );
3029         packValues( callId, callState->reply, v );
3030       }
3031       else
3032       {
3033         DBUS_DEBUG( "call %d: failed: %s", callId.id, v.getError().message.c_str() );
3034         callState->reply = eldbus_message_error_new( callState->message.get(), "org.freedesktop.DBus.Error.Failed", v.getError().message.c_str() );
3035       }
3036       if( !callState->replyRunning )
3037       {
3038         eldbus_connection_send( connection->get(), callState->reply, NULL, NULL, -1 );
3039       }
3040     };
3041     Eldbus_Message* ret = nullptr;
3042     auto args = detail::unpackValues< VEArgs >( callId, msg );
3043     if( args )
3044     {
3045       auto error = [&]( const std::string& txt ) {
3046         if( !callState->reply )
3047         {
3048           DBUS_DEBUG( "call %d: failed: %s", callId.id, txt.c_str() );
3049           callState->reply = eldbus_message_error_new( callState->message.get(), "org.freedesktop.DBus.Error.Failed", txt.c_str() );
3050         }
3051       };
3052       try
3053       {
3054         detail::apply( callback, std::move( retCallback ), std::move( args.getValues() ) );
3055       }
3056       catch( std::exception& e )
3057       {
3058         error( std::string( "unhandled exception (" ) + e.what() + ")" );
3059       }
3060       catch( ... )
3061       {
3062         error( "unhandled exception" );
3063       }
3064
3065       callState->replyRunning = false;
3066       ret = callState->reply;
3067     }
3068     else
3069     {
3070       std::ostringstream err;
3071       err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << eldbus_message_signature_get( msg ) << "'";
3072       auto str = err.str();
3073       ret = eldbus_message_error_new( msg, "org.freedesktop.DBus.Error.InvalidArgs", str.c_str() );
3074     }
3075     return ret;
3076   };
3077
3078   z.id = callId;
3079 }
3080
3081 /// \cond
3082 std::shared_ptr< EldbusConnection > getDBusConnectionByType( ConnectionType tp );
3083 std::shared_ptr< EldbusConnection > getDBusConnectionByName( const std::string& name );
3084 std::string getConnectionName( const std::shared_ptr< EldbusConnection >& );
3085 /// \endcond
3086 }
3087
3088 /// \cond
3089 namespace std
3090 {
3091 template < size_t INDEX, typename... ARGS >
3092 inline auto get( DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) ) &
3093 {
3094   return std::get< INDEX >( v.getValues() );
3095 }
3096 template < size_t INDEX, typename... ARGS >
3097 inline auto get( const DBus::ValueOrError< ARGS... >& v ) -> decltype( std::get< INDEX >( v.getValues() ) )
3098 {
3099   return std::get< INDEX >( v.getValues() );
3100 }
3101 }
3102 /// \endcond
3103
3104 #endif