1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H
5 * Copyright 2020 Samsung Electronics Co., Ltd
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
31 #include <string_view>
34 #include <type_traits>
35 #include <unordered_map>
39 #include <dali/public-api/common/dali-common.h>
40 #include <dali/devel-api/adaptor-framework/accessibility.h>
42 #define ATSPI_PREFIX_PATH "/org/a11y/atspi/accessible/"
43 #define ATSPI_NULL_PATH "/org/a11y/atspi/null"
52 struct DALI_ADAPTOR_API DBusWrapper
54 virtual ~DBusWrapper() = default;
56 enum class ConnectionType
62 #define DEFINE_TYPE(name, eldbus_name, unref_call) \
63 struct name { virtual ~name() = default; }; \
64 using name ## Ptr = std::shared_ptr<name>; \
65 using name ## WeakPtr = std::weak_ptr<name>; \
67 DEFINE_TYPE(Connection, Eldbus_Connection, )
68 DEFINE_TYPE(MessageIter, Eldbus_Message_Iter, eldbus_message_iter_container_close(Value))
69 DEFINE_TYPE(Message, Eldbus_Message, eldbus_message_unref(Value))
70 DEFINE_TYPE(Proxy, Eldbus_Proxy, eldbus_proxy_unref(Value))
71 DEFINE_TYPE(Object, Eldbus_Object, eldbus_object_unref(Value))
72 DEFINE_TYPE(Pending, Eldbus_Pending, )
73 DEFINE_TYPE(EventPropertyChanged, Eldbus_Proxy_Event_Property_Changed, )
76 virtual ConnectionPtr eldbus_address_connection_get_impl(const std::string& addr) = 0;
78 #define eldbus_message_iter_arguments_append_impl_basic_impl(type_set, type_get, sig) \
79 virtual void eldbus_message_iter_arguments_append_impl(const MessageIterPtr &it, type_set src) = 0; \
80 virtual bool eldbus_message_iter_get_and_next_impl(const MessageIterPtr &it, type_get &dst) = 0;
81 #define eldbus_message_iter_arguments_append_impl_basic(type, sig) \
82 eldbus_message_iter_arguments_append_impl_basic_impl(type, type, sig)
84 eldbus_message_iter_arguments_append_impl_basic(uint8_t, y)
85 eldbus_message_iter_arguments_append_impl_basic(uint16_t, q)
86 eldbus_message_iter_arguments_append_impl_basic(uint32_t, u)
87 eldbus_message_iter_arguments_append_impl_basic(uint64_t, t)
88 eldbus_message_iter_arguments_append_impl_basic(int16_t, n)
89 eldbus_message_iter_arguments_append_impl_basic(int32_t, i)
90 eldbus_message_iter_arguments_append_impl_basic(int64_t, x)
91 eldbus_message_iter_arguments_append_impl_basic(double, d)
92 eldbus_message_iter_arguments_append_impl_basic(bool, b)
93 eldbus_message_iter_arguments_append_impl_basic_impl(const std::string&, std::string, s)
94 eldbus_message_iter_arguments_append_impl_basic_impl(const ObjectPath&, ObjectPath, o)
96 #undef eldbus_message_iter_arguments_append_impl_basic
97 #undef eldbus_message_iter_arguments_append_impl_basic_impl
99 virtual MessageIterPtr eldbus_message_iter_container_new_impl(const MessageIterPtr& it, int type, const std::string& sig) = 0;
100 virtual MessageIterPtr eldbus_message_iter_get_and_next_by_type_impl(const MessageIterPtr& it, int type) = 0;
101 virtual MessageIterPtr eldbus_message_iter_get_impl(const MessagePtr& it, bool write) = 0;
102 virtual MessagePtr eldbus_proxy_method_call_new_impl(const ProxyPtr& proxy, const std::string& funcName) = 0;
103 virtual MessagePtr eldbus_proxy_send_and_block_impl(const ProxyPtr& proxy, const MessagePtr& msg) = 0;
104 virtual bool eldbus_message_error_get_impl(const MessagePtr& msg, std::string& name, std::string& text) = 0;
105 virtual std::string eldbus_message_signature_get_impl(const MessagePtr& msg) = 0;
107 using SendCallback = std::function<void(const MessagePtr & msg)>;
108 virtual PendingPtr eldbus_proxy_send_impl(const ProxyPtr& proxy, const MessagePtr& msg, const SendCallback& callback) = 0;
109 virtual std::string eldbus_proxy_interface_get_impl(const ProxyPtr&) = 0;
110 virtual void eldbus_proxy_signal_handler_add_impl(const ProxyPtr& proxy, const std::string& member, const std::function<void(const MessagePtr&)>& cb) = 0;
111 virtual std::string eldbus_message_iter_signature_get_impl(const MessageIterPtr& iter) = 0;
112 virtual MessagePtr eldbus_message_method_return_new_impl(const MessagePtr& msg) = 0;
113 virtual MessagePtr eldbus_message_error_new_impl(const MessagePtr& msg, const std::string& err, const std::string& txt) = 0;
114 virtual PendingPtr eldbus_connection_send_impl(const ConnectionPtr& conn, const MessagePtr& msg) = 0;
115 virtual MessagePtr eldbus_message_signal_new_impl(const std::string& path, const std::string& iface, const std::string& name) = 0;
116 virtual MessagePtr eldbus_message_ref_impl(const MessagePtr& msg) = 0;
117 virtual ConnectionPtr eldbus_connection_get_impl(ConnectionType type) = 0;
118 virtual std::string eldbus_connection_unique_name_get_impl(const ConnectionPtr& conn) = 0;
119 virtual ObjectPtr eldbus_object_get_impl(const ConnectionPtr& conn, const std::string& bus, const std::string& path) = 0;
120 virtual ProxyPtr eldbus_proxy_get_impl(const ObjectPtr& obj, const std::string& interface) = 0;
121 virtual ProxyPtr eldbus_proxy_copy_impl(const ProxyPtr& ptr) = 0;
126 struct char_ptr_deleter
128 void operator()(char* p)
133 std::vector< std::unique_ptr< char, char_ptr_deleter > > storage;
135 const char* add(const char* txt)
137 auto ptr = strdup(txt);
138 storage.push_back(std::unique_ptr< char, char_ptr_deleter >(ptr));
139 return storage.back().get();
141 const char* add(const std::string& txt)
143 return add(txt.c_str());
149 static std::atomic< unsigned int > LastId;
150 unsigned int id = ++LastId;
155 std::string memberName;
156 std::vector< std::pair<std::string, std::string> > in, out; // _Eldbus_Arg_Info
157 std::function< DBusWrapper::MessagePtr(const DBusWrapper::MessagePtr & msg) > callback;
162 std::string memberName;
163 std::vector< std::pair<std::string, std::string> > args;
164 unsigned int uniqueId;
168 CallId setterId, getterId;
169 std::string memberName, typeSignature;
170 std::function< std::string(const DBusWrapper::MessagePtr & src, const DBusWrapper::MessageIterPtr & dst) > getCallback, setCallback;
176 SignalId() = default;
177 SignalId(CallId id) : id(id) {}
179 virtual void add_interface_impl(bool fallback, const std::string& pathName,
180 const ConnectionPtr& connection,
181 std::vector<std::function<void()>>& destructors,
182 const std::string& interfaceName,
183 std::vector< MethodInfo >& dscrMethods,
184 std::vector< PropertyInfo >& dscrProperties,
185 std::vector< SignalInfo >& dscrSignals) = 0;
186 virtual void add_property_changed_event_listener_impl(const ProxyPtr& proxy, const std::string& interface, const std::string& name, std::function< void(const _Eina_Value*) > cb) = 0;
187 static DBusWrapper* Installed();
188 static void Install(std::unique_ptr<DBusWrapper>);
190 StringStorage Strings;
194 enum class MethodType {
195 Method, Getter, Setter
200 template <> struct hash<std::tuple<std::string, std::string, std::string>> {
201 size_t operator () (const std::tuple<std::string, std::string, std::string>& a) const {
202 auto a1 = std::hash<std::string>()(std::get<0>(a));
203 auto a2 = std::hash<std::string>()(std::get<1>(a));
204 auto a3 = std::hash<std::string>()(std::get<2>(a));
206 v = (v * 11400714819323198485llu) + a2;
207 v = (v * 11400714819323198485llu) + a3;
211 template <> struct hash<std::tuple<std::string, std::string, std::string, detail::MethodType>> {
212 size_t operator () (const std::tuple<std::string, std::string, std::string, detail::MethodType>& a) const {
213 auto a1 = std::hash<std::string>()(std::get<0>(a));
214 auto a2 = std::hash<std::string>()(std::get<1>(a));
215 auto a3 = std::hash<std::string>()(std::get<2>(a));
216 auto a4 = static_cast<size_t>(std::get<3>(a));
218 v = (v * 11400714819323198485llu) + a2;
219 v = (v * 11400714819323198485llu) + a3;
220 v = (v * 11400714819323198485llu) + a4;
224 template <> struct hash<std::tuple<std::string, std::string, unsigned int>> {
225 size_t operator () (const std::tuple<std::string, std::string, unsigned int>& a) const {
226 auto a1 = std::hash<std::string>()(std::get<0>(a));
227 auto a2 = std::hash<std::string>()(std::get<1>(a));
228 auto a3 = std::get<2>(a);
230 v = (v * 11400714819323198485llu) + a2;
231 v = (v * 11400714819323198485llu) + a3;
238 template <typename T> struct DBusSigImpl { enum { value = 0, end = 0 }; };
239 template <typename T> struct DBusSig { enum { value = DBusSigImpl<typename std::decay<T>::type>::value, end = DBusSigImpl<typename std::decay<T>::type>::end }; };
240 template <typename T, typename Q, size_t I, size_t S> struct IndexFromTypeTupleImpl {
241 enum { value = std::is_same<typename std::decay<typename std::tuple_element<I, T>::type>::type, Q>::value ? I : IndexFromTypeTupleImpl<T, Q, I + 1, S>::value };
243 template <typename T, typename Q, size_t S> struct IndexFromTypeTupleImpl<T, Q, S, S> { enum { value = S }; };
244 template <typename T, typename Q> struct IndexFromTypeTuple {
245 enum { value = IndexFromTypeTupleImpl<T, typename std::decay<Q>::type, 0, std::tuple_size<T>::value>::value };
247 template <typename T, typename = void> struct Encoder;
248 template <size_t I, size_t S, typename ... ARGS> struct EncoderTuple;
252 template <> struct DBusSigImpl<uint8_t> { enum { value = 'y', end = 0 }; };
253 template <> struct DBusSigImpl<uint16_t> { enum { value = 'q', end = 0 }; };
254 template <> struct DBusSigImpl<uint32_t> { enum { value = 'u', end = 0 }; };
255 template <> struct DBusSigImpl<uint64_t> { enum { value = 't', end = 0 }; };
256 template <> struct DBusSigImpl<int16_t> { enum { value = 'n', end = 0 }; };
257 template <> struct DBusSigImpl<int32_t> { enum { value = 'i', end = 0 }; };
258 template <> struct DBusSigImpl<int64_t> { enum { value = 'x', end = 0 }; };
259 template <> struct DBusSigImpl<double> { enum { value = 'd', end = 0 }; };
260 template <> struct DBusSigImpl<bool> { enum { value = 'b', end = 0 }; };
261 template <> struct DBusSigImpl<std::string> { enum { value = 's', end = 0 }; };
262 template <> struct DBusSigImpl<ObjectPath> { enum { value = 'o', end = 0 }; };
266 #define DBUS_DEBUG( ... ) \
269 DBus::debugPrint( __FILE__, __LINE__, __VA_ARGS__ ); \
272 #define DBUS_W DBusWrapper::Installed()
275 * @brief Template based, single file, wrapper library around eldbus for DBUS based communication.
277 * Main motivation was missing asynchronous calls in AT-SPI library and difficulties,
278 * when using eldbus from C++.
281 * - takes care of marshalling arguments to and from DBUS calls.
282 * - allows synchronous and asynchronous calls.
283 * - allows synchronous and asynchronous listeners on signals.
284 * - manages all involved objects' lifetimes.
285 * - errors are passed as optional-alike objects, no exceptions are used.
286 * - allows setting additional debug-print function for more details about
289 * DBUS's method signatures (and expected return values) are specified as template argument,
290 * using functor syntax. For example:
292 * auto dbus = DBusClient{ ... };
293 * auto v = dbus.method<std::tuple<int, float>(float, float, std::string)>("foo").call(1.0f, 2.0f, "qwe");
295 * means (synchronous) call on dbus object, which takes three arguments (thus making call signature \b dds)
296 * of types float, float and string (float will be automatically converted to double).
297 * Expected return value is std::tuple<int, float>, which gives signature <B>(id)</B> - std::tuple acts
298 * as struct container. Returned value v will be of type ValueOrError<std::tuple<int, float>>.\n
299 * Slightly different (asynchronous) example:
301 * auto dbus = DBusClient{ ... };
302 * std::function<void(ValueOrError<int, float>)> callback;
303 * dbus.method<ValueOrError<int, float>(float, float, std::string)>("foo").asyncCall(callback, 1.0f, 2.0f, "qwe");
305 * Now the call takes the same arguments and has the same signature. But expected values are different -
306 * now the signature is simply \b id. ValueOrError acts in this case as placeholder for list of values,
307 * which DBUS allows as return data. The call itself is asynchronous - instead of expecting reply
308 * you need to pass a callback, which will be called either with received data and error message.
310 * Library is not thread-safe, the same object shouldn't be called from different threads without
311 * synchronization. There's no guarantee, that callbacks will be executed on the same thread.
318 class DBusInterfaceDescription;
321 * @brief Formats debug message and calls debug printer (if any) with it
323 void debugPrint(const char* file, size_t line, const char* format, ...);
326 * @brief Sets debug printer callback, which will be called with debug messages
328 * Callback will be called in various moments of DBus activity. First value passed to callback
329 * is pointer to text, second it's length. Text is ended with 0 (not counted towards it's size),
330 * user can safely printf it.
332 void setDebugPrinter(std::function< void(const char*, size_t) >);
339 Error(std::string msg) : message(std::move(msg))
341 assert(!message.empty());
351 * @brief Value representing data, that came from DBUS or error message
353 * Object of this class either helds series of values (of types ARGS...)
354 * or error message. This object will be true in boolean context, if has data
355 * and false, if an error occured.
356 * It's valid to create ValueOrError object with empty argument list or void:
359 * ValueOrError<void> v2;
361 * Both mean the same - ValueOrError containing no real data and being a marker,
362 * wherever operation successed or failed and containing possible error message.
364 template < typename... ARGS >
369 * @brief Empty constructor. Valid only, if all ARGS types are default constructible.
371 ValueOrError() = default;
374 * @brief Value constructor.
376 * This will be initialized as success with passed in values.
378 ValueOrError(ARGS... t) : value(std::move(t)...) {}
381 * @brief Alternative Value constructor.
383 * This will be initialized as success with passed in values.
385 ValueOrError(std::tuple< ARGS... > t) : value(std::move(t)) {}
388 * @brief Error constructor. This will be initialized as failure with given error message.
390 ValueOrError(Error e) : error(std::move(e))
392 assert(!error.message.empty());
396 * @brief bool operator.
398 * Returns true, if operation was successful (getValues member is callable), or false
399 * when operation failed (getError is callable).
401 explicit operator bool() const
403 return error.message.empty();
407 * @brief Returns error message object.
409 * Returns object containing error message associated with the failed operation.
410 * Only callable, if operation actually failed, otherwise will assert.
412 const Error& getError() const
418 * @brief Returns modifiable tuple of held data.
420 * Returns reference to the internal tuple containing held data.
421 * User can modify (or move) data safely.
422 * Only callable, if operation actually successed, otherwise will assert.
424 std::tuple< ARGS... >& getValues()
431 * @brief Returns const tuple of held data.
433 * Returns const reference to the internal tuple containing held data.
434 * Only callable, if operation actually successed, otherwise will assert.
436 const std::tuple< ARGS... >& getValues() const
443 std::tuple< ARGS... > value;
453 ValueOrError() = default;
454 ValueOrError(std::tuple<> t) {}
455 ValueOrError(Error e) : error(std::move(e))
457 assert(!error.message.empty());
460 explicit operator bool() const
462 return error.message.empty();
464 const Error& getError() const
468 std::tuple<>& getValues()
471 static std::tuple<> t;
474 std::tuple<> getValues() const
485 class ValueOrError< void >
488 ValueOrError() = default;
489 ValueOrError(Success) {}
490 ValueOrError(Error e) : error(std::move(e))
492 assert(!error.message.empty());
495 explicit operator bool() const
497 return error.message.empty();
499 const Error& getError() const
503 std::tuple<>& getValues()
506 static std::tuple<> t;
509 std::tuple<> getValues() const
519 using ObjectPath = ObjectPath;
523 * @brief Class used to marshall DBUS's variant type
525 * Minimalistic class, that allows user to specify DBUS variant type
526 * as argument or return value. You need to pass real type hidden under variant as
527 * template type \b A. At this point library doesn't allow to expected one of few classes
528 * as return data in variant. So for example user can't specify method call, which on return
529 * expects DBUS variant holding either string or int.
531 template < typename A >
538 * @brief Namespace for private, internal functions and classes
542 inline namespace strings {
543 template <std::size_t N>
544 using char_array = std::array<char, N>;
546 constexpr char *xcopy_n(const char *src, size_t n, char *dst)
548 for (std::size_t i = 0; i < n; ++i)
554 template <std::size_t N>
555 constexpr std::size_t xlen(const char (&)[N])
560 template <std::size_t N>
561 constexpr std::size_t xlen(const char_array<N> &)
566 template <typename... Args>
567 constexpr auto concat(const Args &... args)
569 char_array<(1U + ... + xlen(args))> arr{};
570 char *ptr = arr.data();
572 if constexpr (!arr.empty())
573 ((ptr = xcopy_n(std::data(args), xlen(args), ptr)), ...);
578 template<std::size_t... Digits>
580 static constexpr const char value[] = {('0' + static_cast<char>(Digits))..., '\0'};
582 static_assert((true && ... && (Digits < 10)));
585 template<std::size_t Remainder, std::size_t... Digits>
586 struct to_chars_helper : to_chars_helper<Remainder / 10, Remainder % 10, Digits...> {};
588 template<std::size_t... Digits>
589 struct to_chars_helper<0, Digits...> : to_chars<Digits...> {};
591 template<std::size_t N>
592 using to_string = to_chars_helper<N / 10, N % 10>;
595 template < typename T, typename = void >
597 template < typename... ARGS >
598 struct signature< std::tuple< ARGS... > >;
599 template < typename A, typename B >
600 struct signature< std::pair< A, B > >;
601 template < typename A >
602 struct signature< std::vector< A > >;
603 template < typename A, size_t N >
604 struct signature< std::array< A, N > >;
605 template < typename A, typename B >
606 struct signature< std::unordered_map< A, B > >;
607 template < typename A, typename B >
608 struct signature< std::map< A, B > >;
610 template <typename T>
611 struct signature_helper
614 * @brief Returns name of type marshalled, for informative purposes
616 static constexpr std::string_view name()
618 return {T::name_v.data()};
622 * @brief Returns DBUS' signature of type marshalled
624 static constexpr std::string_view sig()
626 return {T::sig_v.data()};
631 * @brief Signature class for marshalling uint8 type.
634 struct signature< uint8_t > : signature_helper<signature<uint8_t>>
636 static constexpr auto name_v = concat("uint8_t");
637 static constexpr auto sig_v = concat("y");
640 * @brief Marshals value v as marshalled type into message
642 static void set(const DBusWrapper::MessageIterPtr& iter, uint8_t v)
644 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
648 * @brief Marshals value from marshalled type into variable v
650 static bool get(const DBusWrapper::MessageIterPtr& iter, uint8_t& v)
652 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
657 * @brief Signature class for marshalling uint16 type.
660 struct signature< uint16_t > : signature_helper<signature<uint16_t>>
662 static constexpr auto name_v = concat("uint16_t");
663 static constexpr auto sig_v = concat("q");
666 * @brief Marshals value v as marshalled type into message
668 static void set(const DBusWrapper::MessageIterPtr& iter, uint16_t v)
670 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
674 * @brief Marshals value from marshalled type into variable v
676 static bool get(const DBusWrapper::MessageIterPtr& iter, uint16_t& v)
678 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
683 * @brief Signature class for marshalling uint32 type.
686 struct signature< uint32_t > : signature_helper<signature<uint32_t>>
688 static constexpr auto name_v = concat("uint32_t");
689 static constexpr auto sig_v = concat("u");
692 * @brief Marshals value v as marshalled type into message
694 static void set(const DBusWrapper::MessageIterPtr& iter, uint32_t v)
696 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
700 * @brief Marshals value from marshalled type into variable v
702 static bool get(const DBusWrapper::MessageIterPtr& iter, uint32_t& v)
704 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
709 * @brief Signature class for marshalling uint64 type.
712 struct signature< uint64_t > : signature_helper<signature<uint64_t>>
714 static constexpr auto name_v = concat("uint64_t");
715 static constexpr auto sig_v = concat("t");
718 * @brief Marshals value v as marshalled type into message
720 static void set(const DBusWrapper::MessageIterPtr& iter, uint64_t v)
722 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
726 * @brief Marshals value from marshalled type into variable v
728 static bool get(const DBusWrapper::MessageIterPtr& iter, uint64_t& v)
730 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
735 * @brief Signature class for marshalling int16 type.
738 struct signature< int16_t > : signature_helper<signature<int16_t>>
740 static constexpr auto name_v = concat("int16_t");
741 static constexpr auto sig_v = concat("n");
744 * @brief Marshals value v as marshalled type into message
746 static void set(const DBusWrapper::MessageIterPtr& iter, int16_t v)
748 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
752 * @brief Marshals value from marshalled type into variable v
754 static bool get(const DBusWrapper::MessageIterPtr& iter, int16_t& v)
756 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
761 * @brief Signature class for marshalling int32 type.
764 struct signature< int32_t > : signature_helper<signature<int32_t>>
766 static constexpr auto name_v = concat("int32_t");
767 static constexpr auto sig_v = concat("i");
770 * @brief Marshals value v as marshalled type into message
772 static void set(const DBusWrapper::MessageIterPtr& iter, int32_t v)
774 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
778 * @brief Marshals value from marshalled type into variable v
780 static bool get(const DBusWrapper::MessageIterPtr& iter, int32_t& v)
782 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
787 * @brief Signature class for marshalling int64 type.
790 struct signature< int64_t > : signature_helper<signature<int64_t>>
792 static constexpr auto name_v = concat("int64_t");
793 static constexpr auto sig_v = concat("x");
796 * @brief Marshals value v as marshalled type into message
798 static void set(const DBusWrapper::MessageIterPtr& iter, int64_t v)
800 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
804 * @brief Marshals value from marshalled type into variable v
806 static bool get(const DBusWrapper::MessageIterPtr& iter, int64_t& v)
808 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
813 * @brief Signature class for marshalling double type.
816 struct signature< double > : signature_helper<signature<double>>
818 static constexpr auto name_v = concat("double");
819 static constexpr auto sig_v = concat("d");
822 * @brief Marshals value v as marshalled type into message
824 static void set(const DBusWrapper::MessageIterPtr& iter, double v)
826 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
830 * @brief Marshals value from marshalled type into variable v
832 static bool get(const DBusWrapper::MessageIterPtr& iter, double& v)
834 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
838 * @brief Marshals value from marshalled type into variable v
840 static bool get(const DBusWrapper::MessageIterPtr& iter, float& v2)
843 auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
844 v2 = static_cast<float>(v);
850 * @brief Signature class for marshalling float type.
853 struct signature< float > : signature_helper<signature<float>>
855 static constexpr auto name_v = concat("float");
856 static constexpr auto sig_v = concat("d");
859 * @brief Marshals value v as marshalled type into message
861 static void set(const DBusWrapper::MessageIterPtr& iter, float v)
863 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
867 * @brief Marshals value from marshalled type into variable v
869 static bool get(const DBusWrapper::MessageIterPtr& iter, double& v)
871 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
875 * @brief Marshals value from marshalled type into variable v
877 static bool get(const DBusWrapper::MessageIterPtr& iter, float& v2)
880 auto r = DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
881 v2 = static_cast<float>(v);
887 * @brief Signature class for marshalling boolean type.
890 struct signature< bool > : signature_helper<signature<bool>>
892 static constexpr auto name_v = concat("bool");
893 static constexpr auto sig_v = concat("b");
896 * @brief Marshals value v as marshalled type into message
898 static void set(const DBusWrapper::MessageIterPtr& iter, bool v)
900 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
904 * @brief Marshals value from marshalled type into variable v
906 static bool get(const DBusWrapper::MessageIterPtr& iter, bool& v)
908 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
912 template < typename T >
913 struct signature<T, typename std::enable_if_t<std::is_enum_v<T>, void>> : signature_helper<signature<T>>
915 static constexpr auto name_v = concat("enum");
916 static constexpr auto sig_v = signature<typename std::underlying_type<T>::type>::sig_v;
919 * @brief Marshals value v as marshalled type into message
921 static void set(const DBusWrapper::MessageIterPtr& iter, T v)
923 signature<typename std::underlying_type<T>::type>::set(iter, static_cast<int64_t>(v));
927 * @brief Marshals value from marshalled type into variable v
929 static bool get(const DBusWrapper::MessageIterPtr& iter, T& v)
931 typename std::underlying_type<T>::type q = 0;
932 if (!signature<typename std::underlying_type<T>::type>::get(iter, q))
935 v = static_cast<T>(q);
941 * @brief Signature class for marshalling string type.
943 * Both (const) char * and std::string types are accepted as value to send.
944 * Only std::string is accepted as value to receive.
947 struct signature< std::string > : signature_helper<signature<std::string>>
949 static constexpr auto name_v = concat("string");
950 static constexpr auto sig_v = concat("s");
953 * @brief Marshals value v as marshalled type into message
955 static void set(const DBusWrapper::MessageIterPtr& iter, const std::string& v)
957 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
961 * @brief Marshals value from marshalled type into variable v
963 static bool get(const DBusWrapper::MessageIterPtr& iter, std::string& v)
965 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
970 struct signature< ObjectPath > : signature_helper<signature<ObjectPath>>
972 static constexpr auto name_v = concat("path");
973 static constexpr auto sig_v = concat("o");
976 * @brief Marshals value v as marshalled type into message
978 static void set(const DBusWrapper::MessageIterPtr& iter, const std::string& v)
980 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
984 * @brief Marshals value v as marshalled type into message
986 static void set(const DBusWrapper::MessageIterPtr& iter, const ObjectPath& v)
988 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
992 * @brief Marshals value v as marshalled type into message
994 static void set(const DBusWrapper::MessageIterPtr& iter, const char* v)
996 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, ObjectPath{ v });
1000 * @brief Marshals value from marshalled type into variable v
1002 static bool get(const DBusWrapper::MessageIterPtr& iter, ObjectPath& v)
1004 return DBUS_W->eldbus_message_iter_get_and_next_impl(iter, v);
1008 * @brief Marshals value from marshalled type into variable v
1010 static bool get(const DBusWrapper::MessageIterPtr& iter, std::string& v)
1013 if (!DBUS_W->eldbus_message_iter_get_and_next_impl(iter, q)) return false;
1014 v = std::move(q.value);
1020 * @brief Signature class for marshalling (const) char * type.
1022 * Both (const) char * and std::string types are accepted as value to send.
1023 * You can't use (const) char * variable type to receive value.
1026 struct signature< char* > : signature_helper<signature<char *>>
1028 static constexpr auto name_v = concat("string");
1029 static constexpr auto sig_v = concat("s");
1032 * @brief Marshals value v as marshalled type into message
1034 static void set(const DBusWrapper::MessageIterPtr& iter, const std::string& v)
1036 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, v);
1040 * @brief Marshals value v as marshalled type into message
1042 static void set(const DBusWrapper::MessageIterPtr& iter, const char* v)
1044 DBUS_W->eldbus_message_iter_arguments_append_impl(iter, std::string{ v });
1048 template < size_t INDEX, typename A, typename... ARGS >
1049 struct signature_tuple_element_type_helper
1051 using type = typename signature_tuple_element_type_helper< INDEX - 1, ARGS... >::type;
1054 template < typename A, typename... ARGS >
1055 struct signature_tuple_element_type_helper< 0, A, ARGS... >
1061 * @brief Helper class to marshall tuples
1063 * This class marshals all elements of the tuple value starting at the index INDEX
1064 * and incrementing. This class recursively calls itself with increasing INDEX value
1065 * until INDEX is equal to SIZE, where recursive calling ends.
1067 template < size_t INDEX, size_t SIZE, typename... ARGS >
1068 struct signature_tuple_helper : signature_helper<signature_tuple_helper<INDEX, SIZE, ARGS...>>
1070 using current_type = typename signature_tuple_element_type_helper< INDEX, ARGS... >::type;
1072 static constexpr auto name_v = concat(signature<current_type>::name_v, ", ", signature_tuple_helper<INDEX + 1, SIZE, ARGS...>::name_v);
1073 static constexpr auto sig_v = concat(signature<current_type>::sig_v, signature_tuple_helper<INDEX + 1, SIZE, ARGS...>::sig_v);
1076 * @brief Marshals value v as marshalled type into message
1078 static void set(const DBusWrapper::MessageIterPtr& iter, const std::tuple< ARGS... >& args)
1080 signature< current_type >::set(iter, std::get< INDEX >(args));
1081 signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::set(iter, args);
1085 * @brief Marshals value from marshalled type into variable v
1087 static bool get(const DBusWrapper::MessageIterPtr& iter, std::tuple< ARGS... >& args)
1089 return signature< current_type >::get(iter, std::get< INDEX >(args)) &&
1090 signature_tuple_helper< INDEX + 1, SIZE, ARGS... >::get(iter, args);
1095 * @brief Helper class to marshall tuples
1097 * This class marks end of the tuple marshalling. Members of this class are called
1098 * when INDEX value is equal to SIZE.
1100 template < size_t SIZE, typename... ARGS >
1101 struct signature_tuple_helper< SIZE, SIZE, ARGS... > : signature_helper<signature_tuple_helper<SIZE, SIZE, ARGS...>>
1103 static constexpr auto name_v = concat("");
1104 static constexpr auto sig_v = concat("");
1107 * @brief Marshals value v as marshalled type into message
1109 static void set(const DBusWrapper::MessageIterPtr& iter, const std::tuple< ARGS... >& args)
1114 * @brief Marshals value from marshalled type into variable v
1116 static bool get(const DBusWrapper::MessageIterPtr& iter, std::tuple< ARGS... >& args)
1123 * @brief Signature class for marshalling tuple of values
1125 * This class marshalls tuple of values. This represents
1126 * DBUS struct typle, encoded with character 'r'
1128 template < typename... ARGS >
1129 struct signature< std::tuple< ARGS... > > : signature_helper<signature<std::tuple<ARGS...>>>
1131 static constexpr auto name_v = concat("tuple<", signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::name_v, ">");
1132 static constexpr auto sig_v = concat("(", signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::sig_v, ")");
1135 * @brief Marshals value v as marshalled type into message
1137 static void set(const DBusWrapper::MessageIterPtr& iter, const std::tuple< ARGS... >& args)
1139 auto entry = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'r', "");
1140 signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::set(entry, args);
1144 * @brief Marshals value from marshalled type into variable v
1146 static bool get(const DBusWrapper::MessageIterPtr& iter, std::tuple< ARGS... >& args)
1148 auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'r');
1149 if (!entry) return false;
1150 return signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::get(entry, args);
1155 * @brief Signature class for marshalling ValueOrError template type
1157 * ValueOrError template type is used to marshall list of values passed to
1158 * DBUS (or received from) at the "top" level. For example ss(s) is represented as
1159 * \code{.cpp} ValueOrError<std::string, std::string, std::tuple<std::string>> \endcode
1160 * While (ss(s)) is represented as
1161 * \code{.cpp} std::tuple<std::string, std::string, std::tuple<std::string>> \endcode
1163 * \code{.cpp} ValueOrError<std::tuple<std::string, std::string, std::tuple<std::string>>> \endcode
1165 template < typename... ARGS >
1166 struct signature< ValueOrError< ARGS... > > : signature_helper<signature<ValueOrError<ARGS...>>>
1168 static constexpr auto name_v = concat("ValueOrError<", signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::name_v, ">");
1169 static constexpr auto sig_v = signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::sig_v;
1172 * @brief Marshals value v as marshalled type into message
1174 static void set(const DBusWrapper::MessageIterPtr& iter, const ValueOrError< ARGS... >& args)
1176 signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::set(iter, args.getValues());
1180 * @brief Marshals value from marshalled type into variable v
1182 static bool get(const DBusWrapper::MessageIterPtr& iter, ValueOrError< ARGS... >& args)
1184 return signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::get(iter, args.getValues());
1189 * @brief Signature class for marshalling ValueOrError<void> type
1192 struct signature< ValueOrError< void > > : signature_helper<signature<ValueOrError<void>>>
1194 static constexpr auto name_v = concat("ValueOrError<void>");
1195 static constexpr auto sig_v = concat("");
1198 * @brief Marshals value v as marshalled type into message
1200 static void set(const DBusWrapper::MessageIterPtr& iter, const ValueOrError< void >& args)
1205 * @brief Marshals value from marshalled type into variable v
1207 static bool get(const DBusWrapper::MessageIterPtr& iter, ValueOrError< void >& args)
1214 * @brief Signature class for marshalling ValueOrError<> type
1217 struct signature< ValueOrError<> > : signature_helper<signature<ValueOrError<>>>
1219 static constexpr auto name_v = concat("ValueOrError<>");
1220 static constexpr auto sig_v = concat("");
1223 * @brief Marshals value v as marshalled type into message
1225 static void set(const DBusWrapper::MessageIterPtr& iter, const ValueOrError<>& args)
1230 * @brief Marshals value from marshalled type into variable v
1232 static bool get(const DBusWrapper::MessageIterPtr& iter, ValueOrError<>& args)
1239 * @brief Signature class for marshalling pair of types
1241 template < typename A, typename B >
1242 struct signature< std::pair< A, B > > : signature_helper<signature<std::pair<A, B>>>
1244 static constexpr auto name_v = concat("pair<", signature_tuple_helper<0, 2, A, B>::name_v, ">");
1245 static constexpr auto sig_v = concat("(", signature_tuple_helper<0, 2, A, B>::sig_v, ")");
1248 * @brief Marshals value v as marshalled type into message
1250 static void set(const DBusWrapper::MessageIterPtr& iter, const std::pair< A, B >& ab, bool dictionary = false)
1252 auto entry = DBUS_W->eldbus_message_iter_container_new_impl(iter, dictionary ? 'e' : 'r', "");
1253 signature_tuple_helper< 0, 2, A, B >::set(entry, ab);
1257 * @brief Marshals value from marshalled type into variable v
1259 static bool get(const DBusWrapper::MessageIterPtr& iter, std::pair< A, B >& ab)
1261 auto entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'r');
1263 entry = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, '{');
1264 if (!entry) return false;
1267 std::tuple< A, B > ab_tmp;
1268 auto z = signature_tuple_helper< 0, 2, A, B >::get(entry, ab_tmp);
1271 ab.first = std::move(std::get< 0 >(ab_tmp));
1272 ab.second = std::move(std::get< 1 >(ab_tmp));
1279 * @brief Signature class for marshalling std::vector template type
1281 * This marshals container's content as DBUS a ascii character type code.
1283 template < typename A >
1284 struct signature< std::vector< A > > : signature_helper<signature<std::vector<A>>>
1286 static constexpr auto name_v = concat("vector<", signature<A>::name_v, ">");
1287 static constexpr auto sig_v = concat("a", signature<A>::sig_v);
1290 * @brief Marshals value v as marshalled type into message
1292 static void set(const DBusWrapper::MessageIterPtr& iter, const std::vector< A >& v)
1294 auto lst = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'a', std::string{signature< A >::sig()});
1298 signature< A >::set(lst, a);
1303 * @brief Marshals value from marshalled type into variable v
1305 static bool get(const DBusWrapper::MessageIterPtr& iter, std::vector< A >& v)
1307 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1308 if (!s) return false;
1311 while (signature< A >::get(s, a))
1312 v.push_back(std::move(a));
1319 * @brief Signature class for marshalling std::array template type
1321 * This marshals container's content as DBUS a ascii character type code.
1323 template < typename A, size_t N >
1324 struct signature< std::array< A, N > > : signature_helper<signature<std::array<A, N>>>
1326 static constexpr auto name_v = concat("array<", signature<A>::name_v, ", ", to_string<N>::value, ">");
1327 static constexpr auto sig_v = concat("a", signature<A>::sig_v);
1330 * @brief Marshals value v as marshalled type into message
1332 static void set(const DBusWrapper::MessageIterPtr& iter, const std::array< A, N >& v)
1334 auto lst = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'a', std::string{signature< A >::sig()});
1338 signature< A >::set(lst, a);
1343 * @brief Marshals value from marshalled type into variable v
1345 static bool get(const DBusWrapper::MessageIterPtr& iter, std::array< A, N >& v)
1347 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1352 if (!signature< A >::get(s, a))
1360 * @brief Signature class for marshalling EldbusVariant type
1362 * This marshals variant's content as DBUS v ascii character type code.
1364 template < typename A >
1365 struct signature< EldbusVariant< A > > : signature_helper<signature<EldbusVariant<A>>>
1367 static constexpr auto name_v = concat("variant<", signature<A>::name_v, ">");
1368 static constexpr auto sig_v = concat("v");
1371 * @brief Marshals value v as marshalled type into message
1373 static void set(const DBusWrapper::MessageIterPtr& iter, const EldbusVariant< A >& v)
1379 * @brief Marshals value v as marshalled type into message
1381 static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1383 auto var = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'v', std::string{signature< A >::sig()});
1384 signature< A >::set(var, v);
1388 * @brief Marshals value from marshalled type into variable v
1390 static bool get(const DBusWrapper::MessageIterPtr& iter, EldbusVariant< A >& v)
1392 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'v');
1395 return signature< A >::get(s, v.value);
1400 * @brief Signature class for marshalling std::unordered_map template type
1402 * This marshals container's content as DBUS {} ascii character type code.
1403 * Note, that library doesnt check, if the key is basic type, as DBUS
1404 * specification mandates.
1405 * User can always exchange std::unordered_map for std::map and the reverse.
1406 * User can receive such values as std::vector of std::pair<key, value> values.
1407 * Order of such values is unspecified.
1409 template < typename A, typename B >
1410 struct signature< std::unordered_map< A, B > > : signature_helper<signature<std::unordered_map<A, B>>>
1412 static constexpr auto name_v = concat("unordered_map<", signature<A>::name_v, ", ", signature<B>::name_v, ">");
1413 static constexpr auto sig_v = concat("a{", signature_tuple_helper<0, 2, A, B>::sig_v, "}");
1416 * @brief Marshals value v as marshalled type into message
1418 static void set(const DBusWrapper::MessageIterPtr& iter, const std::unordered_map< A, B >& v)
1420 auto sig = "{" + std::string{signature_tuple_helper< 0, 2, A, B >::sig()} + "}";
1421 auto lst = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'a', sig);
1425 signature< std::pair< A, B > >::set(lst, a, true);
1430 * @brief Marshals value from marshalled type into variable v
1432 static bool get(const DBusWrapper::MessageIterPtr& iter, std::unordered_map< A, B >& v)
1434 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1438 std::pair< A, B > a;
1439 while (signature< std::pair< A, B > >::get(s, a))
1440 v.insert(std::move(a));
1446 * @brief Signature class for marshalling std::unordered_map template type
1448 * This marshals container's content as DBUS {} ascii character type code.
1449 * Note, that library doesnt check, if the key is basic type, as DBUS
1450 * specification mandates.
1451 * User can always exchange std::unordered_map for std::map and the reverse.
1452 * User can receive such values as std::vector of std::pair<key, value> values.
1453 * Order of such values is unspecified.
1455 template < typename A, typename B >
1456 struct signature< std::map< A, B > > : signature_helper<signature<std::map<A, B>>>
1458 static constexpr auto name_v = concat("map<", signature<A>::name_v, ", ", signature<B>::name_v, ">");
1459 static constexpr auto sig_v = concat("a{", signature_tuple_helper<0, 2, A, B>::sig_v, "}");
1462 * @brief Marshals value v as marshalled type into message
1464 static void set(const DBusWrapper::MessageIterPtr& iter, const std::map< A, B >& v)
1466 auto sig = "{" + std::string{signature_tuple_helper< 0, 2, A, B >::sig()} + "}";
1467 auto lst = DBUS_W->eldbus_message_iter_container_new_impl(iter, 'a', sig);
1471 signature< std::pair< A, B > >::set(lst, a, true);
1476 * @brief Marshals value from marshalled type into variable v
1478 static bool get(const DBusWrapper::MessageIterPtr& iter, std::map< A, B >& v)
1480 auto s = DBUS_W->eldbus_message_iter_get_and_next_by_type_impl(iter, 'a');
1483 std::pair< A, B > a;
1484 while (signature< std::pair< A, B > >::get(s, a))
1485 v.insert(std::move(a));
1491 * @brief Signature helper class for marshalling const reference types
1493 template < typename A >
1494 struct signature< const A& > : signature_helper<signature<const A &>>
1496 static constexpr auto name_v = concat("const ", signature<A>::name_v, "&");
1497 static constexpr auto sig_v = signature<A>::sig_v;
1500 * @brief Marshals value v as marshalled type into message
1502 static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1504 signature< A >::set(iter, v);
1508 * @brief Marshals value from marshalled type into variable v
1510 static void get(const DBusWrapper::MessageIterPtr& iter, A& v)
1512 signature< A >::get(iter, v);
1517 * @brief Signature helper class for marshalling reference types
1519 template < typename A >
1520 struct signature< A& > : signature_helper<signature<A &>>
1522 static constexpr auto name_v = concat(signature<A>::name_v, "&");
1523 static constexpr auto sig_v = signature<A>::sig_v;
1526 * @brief Marshals value v as marshalled type into message
1528 static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1530 signature< A >::set(iter, v);
1534 * @brief Marshals value from marshalled type into variable v
1536 static void get(const DBusWrapper::MessageIterPtr& iter, A& v)
1538 signature< A >::get(iter, v);
1543 * @brief Signature helper class for marshalling const types
1545 template < typename A >
1546 struct signature< const A > : signature_helper<signature<const A>>
1548 static constexpr auto name_v = concat("const ", signature<A>::name_v);
1549 static constexpr auto sig_v = signature<A>::sig_v;
1552 * @brief Marshals value v as marshalled type into message
1554 static void set(const DBusWrapper::MessageIterPtr& iter, const A& v)
1556 signature< A >::set(iter, v);
1560 * @brief Marshals value from marshalled type into variable v
1562 static void get(const DBusWrapper::MessageIterPtr& iter, A& v)
1564 signature< A >::get(iter, v);
1568 using CallId = DBusWrapper::CallId;
1570 template < typename ValueType >
1571 ValueType unpackValues(CallId callId, const DBusWrapper::MessagePtr& msg)
1573 static const std::string sig{signature< ValueType >::sig().data()};
1575 auto iter = DBUS_W->eldbus_message_iter_get_impl(msg, false);
1580 if (!signature< ValueType >::get(iter, r))
1582 DBUS_DEBUG("ValueType is %s", signature< ValueType >::name().data());
1583 r = Error{ "call " + std::to_string(callId.id) + ": failed to unpack values, got signature '" +
1584 DBUS_W->eldbus_message_signature_get_impl(msg) + "', expected '" + sig + "'" };
1589 r = Error{ "call " + std::to_string(callId.id) + ": failed to get iterator" };
1594 inline void packValues_helper(const DBusWrapper::MessageIterPtr&) {}
1596 template < typename A, typename... ARGS >
1597 void packValues_helper(const DBusWrapper::MessageIterPtr& iter, A&& a, ARGS&&... r)
1599 signature< A >::set(iter, std::forward< A >(a));
1600 packValues_helper(iter, std::forward< ARGS >(r)...);
1603 template < typename... ARGS >
1604 void packValues(CallId callId, const DBusWrapper::MessagePtr& msg, ARGS&&... r)
1606 auto iter = DBUS_W->eldbus_message_iter_get_impl(msg, true);
1607 packValues_helper(iter, std::forward< ARGS >(r)...);
1610 struct ConnectionState
1612 DBusWrapper::ConnectionPtr connection;
1613 DBusWrapper::ObjectPtr object;
1614 DBusWrapper::ProxyPtr proxy, propertiesProxy;
1617 template < typename RETTYPE, typename... ARGS >
1618 RETTYPE call(CallId callId, const ConnectionState& connectionState, bool property, const std::string& funcName, const ARGS&... args)
1620 const auto& proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
1623 DBUS_DEBUG("call %d: not initialized", callId.id);
1624 return Error{ "not initialized" };
1627 DBUS_DEBUG("call %d: calling '%s'", callId.id, funcName.c_str());
1628 auto msg = DBUS_W->eldbus_proxy_method_call_new_impl(proxy, funcName);
1631 DBUS_DEBUG("call %d: failed", callId.id);
1632 return Error{ "failed to create message" };
1635 detail::packValues(callId, msg, args...);
1636 auto reply = DBUS_W->eldbus_proxy_send_and_block_impl(proxy, msg);
1637 DBUS_DEBUG("call %d: calling '%s' done", callId.id, funcName.c_str());
1640 DBUS_DEBUG("call %d: failed", callId.id);
1641 return Error{ "eldbus returned null as reply" };
1643 std::string errname, errmsg;
1644 if (DBUS_W->eldbus_message_error_get_impl(reply, errname, errmsg))
1646 DBUS_DEBUG("call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str());
1647 return Error{ errname + ": " + errmsg };
1649 DBUS_DEBUG("call %d: got reply with signature '%s'", callId.id,
1650 DBUS_W->eldbus_message_signature_get_impl(reply).c_str());
1651 return detail::unpackValues< RETTYPE >(callId, reply);
1654 template < typename RETTYPE, typename... ARGS >
1655 void asyncCall(CallId callId, const ConnectionState& connectionState,
1656 bool property, const std::string& funcName,
1657 std::function< void(RETTYPE) > callback, const ARGS&... args)
1659 const auto& proxy = property ? connectionState.propertiesProxy : connectionState.proxy;
1662 DBUS_DEBUG("call %d: not initialized", callId.id);
1663 callback(Error{ "not initialized" });
1667 auto msg = DBUS_W->eldbus_proxy_method_call_new_impl(proxy, funcName);
1670 DBUS_DEBUG("call %d: failed", callId.id);
1671 callback(Error{ "failed to create message" });
1675 detail::packValues(callId, msg, args...);
1676 auto pending = DBUS_W->eldbus_proxy_send_impl(proxy, msg, [callback, callId, proxy](const DBusWrapper::MessagePtr& reply) {
1677 DBUS_DEBUG("call %d: calling done", callId.id);
1680 DBUS_DEBUG("call %d: failed", callId.id);
1681 callback(Error{ "eldbus returned null as reply" });
1685 std::string errname, errmsg;
1686 if (DBUS_W->eldbus_message_error_get_impl(reply, errname, errmsg))
1688 DBUS_DEBUG("call %d: %s: %s", callId.id, errname.c_str(), errmsg.c_str());
1689 callback(Error{ errname + ": " + errmsg });
1693 DBUS_DEBUG("call %d: got reply with signature '%s'", callId.id,
1694 DBUS_W->eldbus_message_signature_get_impl(reply).c_str());
1695 callback(detail::unpackValues< RETTYPE >(callId, reply));
1702 DBUS_DEBUG("call %d: call sent", callId.id);
1706 DBUS_DEBUG("call %d: failed to send call", callId.id);
1707 callback(Error{ "failed to send call" });
1711 inline void displayDebugCallInfo(CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName)
1713 DBUS_DEBUG("call %d: %s iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str());
1716 inline void displayDebugCallInfoSignal(CallId callId, const std::string& funcName, const std::string& info, const std::string& interfaceName)
1718 DBUS_DEBUG("call %d: %s signal iname = %s fname = %s", callId.id, info.c_str(), interfaceName.c_str(), funcName.c_str());
1721 inline void displayDebugCallInfoProperty(CallId callId, const std::string& funcName, std::string info, const std::string& interfaceName,
1722 const std::string& propertyName)
1724 DBUS_DEBUG("call %d: %s iname = %s pname = %s", callId.id, info.c_str(), interfaceName.c_str(), propertyName.c_str());
1727 using StringStorage = DBusWrapper::StringStorage;
1729 template < typename A, typename... ARGS >
1730 struct EldbusArgGenerator_Helper
1732 static void add(std::vector< std::pair<std::string, std::string> >& r)
1735 auto sig = std::string{signature< A >::sig()};
1736 assert(!sig.empty());
1737 auto name = "p" + std::to_string(s + 1);
1738 r.push_back({ std::move(sig), std::move(name) });
1739 EldbusArgGenerator_Helper<ARGS...>::add(r);
1744 struct EldbusArgGenerator_Helper< void >
1746 static void add(std::vector< std::pair<std::string, std::string> >&)
1752 struct EldbusArgGenerator_Helper< ValueOrError< void >, void >
1754 static void add(std::vector< std::pair<std::string, std::string> >&)
1759 struct EldbusArgGenerator_Helper< ValueOrError<>, void >
1761 static void add(std::vector< std::pair<std::string, std::string> >&)
1766 template < typename... ARGS >
1767 struct EldbusArgGenerator_Helper< std::tuple< ARGS... > >
1769 static void add(std::vector< std::pair<std::string, std::string> >& r)
1771 EldbusArgGenerator_Helper< ARGS..., void >::add(r);
1775 template < typename RetType >
1776 struct dbus_interface_return_type_traits
1778 using type = ValueOrError< RetType >;
1781 template < typename... ARGS >
1782 struct dbus_interface_return_type_traits< ValueOrError< ARGS... > >
1784 using type = ValueOrError< ARGS... >;
1787 template < typename T >
1788 struct dbus_interface_traits;
1789 template < typename RetType, typename... ARGS >
1790 struct dbus_interface_traits< RetType(ARGS...) >
1792 using Ret = typename dbus_interface_return_type_traits< RetType >::type;
1793 using SyncCB = std::function< Ret(ARGS...) >;
1794 using AsyncCB = std::function< void(std::function< void(Ret) >, ARGS...) >;
1795 using VEArgs = ValueOrError< ARGS... >;
1798 template < typename T >
1799 struct EldbusArgGenerator_Args;
1800 template < typename RetType, typename... ARGS >
1801 struct EldbusArgGenerator_Args< RetType(ARGS...) >
1803 static std::string name()
1805 return std::string{signature_tuple_helper< 0, sizeof...(ARGS), ARGS... >::name()};
1807 static std::vector< std::pair<std::string, std::string> > get()
1809 std::vector< std::pair<std::string, std::string> > tmp;
1810 EldbusArgGenerator_Helper< ARGS..., void >::add(tmp);
1815 template < typename T >
1816 struct EldbusArgGenerator_ReturnType;
1817 template < typename RetType, typename... ARGS >
1818 struct EldbusArgGenerator_ReturnType< RetType(ARGS...) >
1820 static std::string name()
1822 return std::string{signature< RetType >::name()};
1824 static std::vector< std::pair<std::string, std::string> > get()
1826 std::vector< std::pair<std::string, std::string> > tmp;
1827 EldbusArgGenerator_Helper< RetType, void >::add(tmp);
1832 template < typename T >
1833 struct EldbusArgGenerator_ReturnType;
1834 template < typename... ARGS >
1835 struct EldbusArgGenerator_ReturnType< void(ARGS...) >
1837 static std::string name()
1841 static std::vector< std::pair<std::string, std::string> > get()
1849 using ConnectionType = DBusWrapper::ConnectionType;
1852 * @brief Class representing client's end of DBUS connection
1854 * Allows calling (synchronous and asynchronous) methods on selected interface
1855 * Allows (synchronous and asynchronous) setting / getting properties.
1856 * Allows registering signals.
1860 struct ConnectionInfo
1862 std::string interfaceName, busName, pathName;
1866 * @brief Default constructor, creates non-connected object.
1868 DBusClient() = default;
1871 * @brief Connects to dbus choosen by tp, using given arguments
1873 * @param bus_name name of the bus to connect to
1874 * @param path_name object's path
1875 * @param interface_name interface name
1877 DBusClient(std::string busName_, std::string pathName_, std::string interfaceName_,
1881 * @brief Connects to dbus using connection conn
1883 * @param bus_name name of the bus to connect to
1884 * @param path_name object's path
1885 * @param interface_name interface name
1886 * @param conn connection object from getDBusConnectionByType call
1888 DBusClient(std::string busName_, std::string pathName_, std::string interfaceName_,
1889 const DBusWrapper::ConnectionPtr& conn = {});
1892 * @brief Destructor object.
1894 * All signals added will be disconnected.
1895 * All asynchronous calls will be cancelled, their callback's will be called
1896 * with failure message.
1898 ~DBusClient() = default;
1899 DBusClient(const DBusClient&) = delete;
1900 DBusClient(DBusClient&&) = default;
1902 DBusClient& operator=(DBusClient&&) = default;
1903 DBusClient& operator=(const DBusClient&) = delete;
1906 * @brief bool operator
1908 * Returns true, if object is connected to DBUS
1910 explicit operator bool() const
1912 return bool(connectionState->proxy);
1916 * @brief Helper class for calling a method
1918 * Template type T defines both arguments sent to the method
1919 * and expected values. Receiving different values will be reported as
1920 * error. For example:
1921 * \code{.cpp} Method<int(float, float)> \endcode
1922 * defines method, which takes two arguments (two floats) and return
1923 * single value of type int.
1925 template < typename T >
1928 using RetType = typename detail::dbus_interface_traits< T >::Ret;
1929 const detail::ConnectionState& connectionState;
1930 std::string funcName;
1932 std::shared_ptr< ConnectionInfo > connectionInfo;
1935 * @brief Executes synchronous call on DBUS's method
1937 * The function returns ValueOrError<...> object, which
1938 * contains either received values or error message.
1940 * @param args arguments to pass to the method
1942 template < typename... ARGS >
1943 RetType call(const ARGS&... args)
1945 detail::CallId callId;
1946 detail::displayDebugCallInfo(callId, funcName, info, connectionInfo->interfaceName);
1947 return detail::call< RetType >(callId, connectionState, false, funcName, args...);
1951 * @brief Executes asynchronous call on DBUS's method
1953 * The function calls callback with either received values or error message.
1955 * @param callback callback functor, which will be called with return value(s) or error message
1956 * @param args arguments to pass to the method
1958 template < typename... ARGS >
1959 void asyncCall(std::function< void(RetType) > callback, const ARGS&... args)
1961 detail::CallId callId;
1962 detail::displayDebugCallInfo(callId, funcName, info, connectionInfo->interfaceName);
1963 detail::asyncCall< RetType >(callId, connectionState, false, funcName, std::move(callback), args...);
1968 * @brief Helper class for calling a property
1970 * Template type T defines type of the value hidden under property.
1971 * Note, that library automatically wraps both sent and received value into
1972 * DBUS's wrapper type.
1974 template < typename T >
1977 using RetType = typename detail::dbus_interface_return_type_traits< T >::type;
1978 using VariantRetType = typename detail::dbus_interface_return_type_traits< EldbusVariant< T > >::type;
1979 const detail::ConnectionState& connectionState;
1980 std::string propName;
1982 std::shared_ptr< ConnectionInfo > connectionInfo;
1985 * @brief executes synchronous get on property
1987 * The function returns ValueOrError<...> object, which
1988 * contains either received values or error message.
1992 detail::CallId callId;
1993 detail::displayDebugCallInfoProperty(callId, "Get", info, connectionInfo->interfaceName, propName);
1994 auto z = detail::call< VariantRetType >(callId, connectionState, true, "Get", connectionInfo->interfaceName, propName);
1996 return z.getError();
1997 return { std::get< 0 >(z.getValues()).value };
2001 * @brief executes asynchronous get on property
2003 * The function calls callback with either received values or error message.
2005 * @param callback callback functor, which will be called with return value(s) or error message
2007 void asyncGet(std::function< void(RetType) > callback)
2009 detail::CallId callId;
2010 detail::displayDebugCallInfoProperty(callId, "Get", info, connectionInfo->interfaceName, propName);
2011 auto cc = [callback](VariantRetType reply) {
2013 callback(std::move(std::get< 0 >(reply.getValues()).value));
2015 callback(reply.getError());
2017 detail::asyncCall< VariantRetType >(callId, connectionState, true, "Get", std::move(cc), connectionInfo->interfaceName, propName);
2021 * @brief executes synchronous set on property
2023 * The function returns ValueOrError<void> object, with
2024 * possible error message.
2026 ValueOrError< void > set(const T& r)
2028 detail::CallId callId;
2029 detail::displayDebugCallInfoProperty(callId, "Set", info, connectionInfo->interfaceName, propName);
2030 EldbusVariant< T > variantValue{ std::move(r) };
2031 return detail::call< ValueOrError< void > >(callId, connectionState, true, "Set", connectionInfo->interfaceName, propName, variantValue);
2035 * @brief executes asynchronous get on property
2037 * The function calls callback with either received values or error message.
2039 * @param callback callback functor, which will be called with return value(s) or error message
2041 void asyncSet(std::function< void(ValueOrError< void >) > callback, const T& r)
2043 detail::CallId callId;
2044 detail::displayDebugCallInfoProperty(callId, "Set", info, connectionInfo->interfaceName, propName);
2045 EldbusVariant< T > variantValue{ std::move(r) };
2046 detail::asyncCall< ValueOrError< void > >(callId, connectionState, true, "Set", std::move(callback), connectionInfo->interfaceName, propName, variantValue);
2051 * @brief Constructs Property<...> object for calling properties
2053 * The function constructs and returns proxy object for calling property.
2055 * @param propName property name to set and / or query
2057 template < typename PropertyType >
2058 Property< PropertyType > property(std::string propName)
2060 return Property< PropertyType >{*connectionState, std::move(propName), info, connectionInfo};
2064 * @brief Constructs Method<...> object for calling methods
2066 * The function constructs and returns proxy object for calling method.
2068 * @param funcName function name to call
2070 template < typename MethodType >
2071 Method< MethodType > method(std::string funcName)
2073 return Method< MethodType >{*connectionState, std::move(funcName), info, connectionInfo};
2077 * @brief Registers notification callback, when property has changed
2079 * The callback will be called with new value, when property's value has changed.
2080 * Note, that template type V must match expected type, otherwise undefined behavior will occur,
2081 * there's no check for this.
2083 template < typename V >
2084 void addPropertyChangedEvent(std::string propertyName, std::function< void(V) > callback)
2086 detail::CallId callId;
2087 detail::displayDebugCallInfoSignal(callId, propertyName, info, connectionInfo->interfaceName);
2088 DBUS_DEBUG("call %d: adding property", callId.id);
2089 auto& cI = this->connectionInfo;
2090 DBUS_W->add_property_changed_event_listener_impl(connectionState->proxy, cI->interfaceName, propertyName,
2091 [callback](const _Eina_Value* newValue) {
2093 if (!getFromEinaValue(newValue, &val))
2095 DBUS_DEBUG("unable to get property's value");
2103 * @brief Registers callback on the DBUS' signal
2105 * The function registers callback signalName. When signal comes, callback will be called.
2106 * Callback object will exists as long as signal is registered. You can unregister signal
2107 * by destroying DBusClient object.
2109 * @param signalName name of the signal to register
2110 * @param callback callback to call
2112 template < typename SignalType >
2113 void addSignal(std::string signalName, std::function< SignalType > callback)
2115 detail::CallId callId;
2116 detail::displayDebugCallInfoSignal(callId, signalName, info, connectionInfo->interfaceName);
2117 DBUS_W->eldbus_proxy_signal_handler_add_impl(connectionState->proxy, signalName,
2118 [callId, callback, signalName](const DBusWrapper::MessagePtr& msg) -> void {
2119 std::string errname, aux;
2120 if (DBUS_W->eldbus_message_error_get_impl(msg, errname, aux))
2122 DBUS_DEBUG("call %d: Eldbus error: %s %s", callId.id, errname.c_str(), aux.c_str());
2125 DBUS_DEBUG("call %d: received signal with signature '%s'", callId.id, DBUS_W->eldbus_message_signature_get_impl(msg).c_str());
2126 using ParamsType = typename detail::dbus_interface_traits< SignalType >::VEArgs;
2127 auto params = detail::unpackValues< ParamsType >(callId, msg);
2130 DBUS_DEBUG("call %d: failed: %s", callId.id, params.getError().message.c_str());
2135 std::apply(callback, params.getValues());
2137 catch (const Dali::DaliException &e)
2139 DBUS_DEBUG("unhandled exception");
2146 std::unique_ptr<detail::ConnectionState> connectionState{ new detail::ConnectionState };
2148 std::shared_ptr< ConnectionInfo > connectionInfo;
2150 static bool getFromEinaValue(const _Eina_Value* v, void* dst);
2154 * @brief Helper class describing DBUS's server interface
2157 class DBusInterfaceDescription
2159 friend class DBusServer;
2162 using MethodInfo = DBusWrapper::MethodInfo;
2163 using SignalInfo = DBusWrapper::SignalInfo;
2164 using PropertyInfo = DBusWrapper::PropertyInfo;
2165 using SignalId = DBusWrapper::SignalId;
2168 * @brief Creates empty interface description with given name
2170 * @param interfaceName name of the interface
2172 DBusInterfaceDescription(std::string interfaceName);
2175 * @brief adds new, synchronous method to the interface
2177 * When method memberName is called on DBUS, callback functor will be called
2178 * with values received from DBUS. callback won't be called, if method was
2179 * called with invalid signature. Value returned from functor (or error message)
2180 * will be marshalled back to the caller.
2182 * Template type T defines both arguments sent to the method
2183 * and expected values. Receiving different values will be reported as
2184 * error. For example:
2185 * \code{.cpp} Method<int(float, float)> \endcode
2186 * defines method, which takes two arguments (two floats) and return
2187 * single value of type int.
2189 * @param memberName name of the method
2190 * @param callback functor, which will be called
2192 template < typename T >
2193 void addMethod(const std::string& memberName, typename detail::dbus_interface_traits< T >::SyncCB callback)
2195 detail::CallId callId;
2197 methods.push_back(std::move(mi));
2198 auto& z = methods.back();
2199 z.in = detail::EldbusArgGenerator_Args< T >::get();
2200 z.out = detail::EldbusArgGenerator_ReturnType< T >::get();
2201 z.memberName = memberName;
2202 DBUS_DEBUG("call %d: method %s, in %s, out %s", callId.id, memberName.c_str(),
2203 detail::EldbusArgGenerator_Args< T >::name().c_str(),
2204 detail::EldbusArgGenerator_ReturnType< T >::name().c_str());
2205 z.callback = construct< T >(callId, callback);
2210 * @brief adds new, synchronous property to the interface
2212 * When property memberName is called on DBUS, respective callback functor will be called
2213 * with values received from DBUS. callback won't be called, if method was
2214 * called with invalid signature. Value returned from functor (or error message)
2215 * will be marshalled back to the caller.
2217 * Template type T defines type of the value hidden under property.
2218 * Note, that library automatically wraps both sent and received value into
2219 * DBUS's wrapper type.
2221 * @param memberName name of the method
2222 * @param getter functor, which will be called when property is being read
2223 * @param setter functor, which will be called when property is being set
2225 template < typename T >
2226 void addProperty(const std::string& memberName, std::function< ValueOrError< T >() > getter, std::function< ValueOrError< void >(T) > setter)
2228 properties.push_back({});
2229 auto& z = properties.back();
2230 z.memberName = memberName;
2231 z.typeSignature = detail::signature< T >::sig();
2234 detail::CallId getterId;
2235 z.getterId = getterId;
2236 DBUS_DEBUG("call %d: property %s (get) type %s", getterId.id, memberName.c_str(), detail::signature< T >::name().data());
2237 z.getCallback = [=](const DBusWrapper::MessagePtr& src, const DBusWrapper::MessageIterPtr& dst) -> std::string {
2240 auto v = std::apply(getter, std::tuple<>{});
2243 detail::signature< T >::set(dst, std::get< 0 >(v.getValues()));
2244 DBUS_DEBUG("call %d: success", getterId.id);
2247 DBUS_DEBUG("call %d: failed: %s", getterId.id, v.getError().message.c_str());
2248 return v.getError().message;
2250 catch (std::exception & e)
2252 return std::string("unhandled exception (") + e.what() + ")";
2254 catch (const Dali::DaliException &e)
2256 return std::string("unhandled exception (") + e.condition + ")";
2262 detail::CallId setterId;
2263 z.setterId = setterId;
2264 DBUS_DEBUG("call %d: property %s (set) type %s", setterId.id, memberName.c_str(), detail::signature< T >::name().data());
2265 z.setCallback = [=](const DBusWrapper::MessagePtr& src, const DBusWrapper::MessageIterPtr& src_iter) -> std::string {
2266 std::tuple< T > value;
2267 auto src_signature = DBUS_W->eldbus_message_iter_signature_get_impl(src_iter);
2268 if (detail::signature< T >::get(src_iter, std::get< 0 >(value)))
2272 auto v = std::apply(setter, std::move(value));
2275 DBUS_DEBUG("call %d: success", setterId.id);
2278 DBUS_DEBUG("call %d: failed: %s", setterId.id, v.getError().message.c_str());
2279 return v.getError().message;
2281 catch (std::exception & e)
2283 return std::string("unhandled exception (") + e.what() + ")";
2285 catch (const Dali::DaliException &e)
2287 return std::string("unhandled exception (") + e.condition + ")";
2290 DBUS_DEBUG("call %d: failed to unpack values, got signature '%s', expected '%s'", setterId.id,
2291 src_signature.c_str(), detail::signature< T >::sig().data());
2292 return "call " + std::to_string(setterId.id) + ": failed to unpack values, got signature '" +
2293 src_signature + "', expected '" + std::string{detail::signature< T >::sig()} + "'";
2299 * @brief adds new signal to the interface
2301 * Template types ARGS defines values, which will be emited with the signal
2303 * @param memberName name of the method
2305 template < typename... ARGS >
2306 SignalId addSignal(const std::string& memberName)
2308 detail::CallId callId;
2309 signals.push_back({});
2310 auto& z = signals.back();
2311 z.memberName = memberName;
2312 z.args = detail::EldbusArgGenerator_Args< void(ARGS...) >::get(DBUS_W->Strings);
2314 DBUS_DEBUG("call %d: signal %s", callId.id, memberName.c_str());
2315 return SignalId{ callId };
2319 std::vector< MethodInfo > methods;
2320 std::vector< PropertyInfo > properties;
2321 std::vector< SignalInfo > signals;
2322 std::string interfaceName;
2324 template < typename T >
2325 std::function< DBusWrapper::MessagePtr(const DBusWrapper::MessagePtr & msg) > construct(detail::CallId callId,
2326 typename detail::dbus_interface_traits< T >::SyncCB callback)
2328 using VEArgs = typename detail::dbus_interface_traits< T >::VEArgs;
2329 return [=](const DBusWrapper::MessagePtr& msg) -> DBusWrapper::MessagePtr {
2330 DBUS_DEBUG("call %d: entering", callId.id);
2331 DBusWrapper::MessagePtr ret = {};
2332 auto args = detail::unpackValues< VEArgs >(callId, msg);
2337 auto v = std::apply(callback, std::move(args.getValues()));
2340 DBUS_DEBUG("call %d: success", callId.id);
2341 ret = DBUS_W->eldbus_message_method_return_new_impl(msg);
2342 detail::packValues(callId, ret, v);
2346 DBUS_DEBUG("call %d: failed: %s", callId.id, v.getError().message.c_str());
2347 ret = DBUS_W->eldbus_message_error_new_impl(msg, "org.freedesktop.DBus.Error.Failed", v.getError().message);
2350 catch (std::exception & e)
2352 auto txt = std::string("unhandled exception (") + e.what() + ")";
2353 DBUS_DEBUG("call %d: failed: %s", callId.id, txt.c_str());
2354 ret = DBUS_W->eldbus_message_error_new_impl(msg, "org.freedesktop.DBus.Error.Failed", txt);
2356 catch (const Dali::DaliException &e)
2358 auto txt = std::string("unhandled exception (") + e.condition + ")";
2359 DBUS_DEBUG("call %d: failed: %s", callId.id, txt.c_str());
2360 ret = DBUS_W->eldbus_message_error_new_impl(msg, "org.freedesktop.DBus.Error.Failed", txt);
2365 std::ostringstream err;
2366 err << "expected signature '" << detail::signature< VEArgs >::sig() << "', got '" << DBUS_W->eldbus_message_signature_get_impl(msg) << "'";
2367 auto str = err.str();
2368 DBUS_DEBUG("call %d: failed: %s", callId.id, str.c_str());
2369 ret = DBUS_W->eldbus_message_error_new_impl(msg, "org.freedesktop.DBus.Error.InvalidArgs", str);
2377 * @brief Class representing server's end of DBUS connection
2379 * Allows listening (synchronously and asynchronously) on methods on selected interface
2380 * Allows listening (synchronously and asynchronously) on setting / getting properties.
2381 * Allows emiting signals.
2387 * @brief Constructs non-connected dbus server.
2389 DBusServer() = default;
2392 * @brief Constructs dbus server on either system or user dbus connection.
2394 DBusServer(ConnectionType tp);
2397 * @brief Constructs dbus server on connection from getDBusConnectionByType
2399 DBusServer(const DBusWrapper::ConnectionPtr& conn);
2404 * Destructor will properly destroy everything. Destructor will cancel
2407 ~DBusServer() = default;
2409 DBusServer(const DBusServer&) = delete;
2410 DBusServer(DBusServer&&) = default;
2412 DBusServer& operator=(DBusServer&&) = default;
2413 DBusServer& operator=(const DBusServer&) = delete;
2416 * @brief Registers interface on given path name
2418 * @param pathName path object to register interface on.
2422 void addInterface(const std::string& pathName, DBusInterfaceDescription& dscr, bool fallback = false);
2425 * @brief Gets bus name of the current connection (must be connected)
2427 std::string getBusName() const;
2430 * @brief Returns connection object for this dbus server object
2432 * @return connection object
2434 DBusWrapper::ConnectionPtr getConnection();
2437 * @brief Emits signal
2439 * Emits signal based only on data passed to the function
2441 * @param signal identifier of the signal
2442 * @param args values to emit
2444 template < typename... ARGS >
2445 void emit2(const std::string& path, const std::string& interfaceName,
2446 const std::string& signalName, const ARGS&... args)
2448 auto msg = DBUS_W->eldbus_message_signal_new_impl(path, interfaceName, signalName);
2450 detail::packValues(id, msg, args...);
2451 DBUS_W->eldbus_connection_send_impl(connection, msg);
2455 * @brief Returns current object path, when handling call to property / method
2457 * User can call this function from inside callback used to handle property / method calls.
2458 * It will retrieve object's path used in the call. Note, that in asynchronous handling
2459 * of those calls user need to retrieve and store the current object / current connection
2460 * as the value will change at the moment user's callback handling will exit. For example:
2462 * DBusInterfaceDescription interface{"name"};
2463 * auto handler_later = [](std::function<void(void)> done_cb) {
2464 * // process something later on
2465 * DBusServer::getCurrentObjectPath(); // this will return empty string
2467 * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
2468 * DBusServer::getCurrentObjectPath(); // this will current object's path
2470 * // do some processing later on and call done_cb, when it's done
2471 * register_to_call_sometime_later_on(std::move(done_cb));
2475 static std::string getCurrentObjectPath() { return currentObjectPath; }
2478 * @brief Returns current connection object, when handling call to property / method
2480 * User can call this function from inside callback used to handle property / method calls.
2481 * It will retrieve object's path used in the call. Note, that in asynchronous handling
2482 * of those calls user need to retrieve and store the current object / current connection
2483 * as the value will change at the moment user's callback handling will exit. For example:
2485 * DBusInterfaceDescription interface{"name"};
2486 * auto handler_later = [](std::function<void(void)> done_cb) {
2487 * // process something later on
2488 * DBusServer::getCurrentObjectPath(); // this will return empty string
2490 * interface.addAsyncMethod<void()>("m", [=](std::function<void(void)> done_cb) {
2491 * DBusServer::getCurrentObjectPath(); // this will current object's path
2493 * // do some processing later on and call done_cb, when it's done
2494 * register_to_call_sometime_later_on(std::move(done_cb));
2498 static const DBusWrapper::ConnectionPtr& getCurrentConnection() { return currentConnection; }
2501 class CurrentObjectSetter
2504 CurrentObjectSetter(DBusWrapper::ConnectionPtr con, std::string path)
2506 currentObjectPath = std::move(path);
2507 currentConnection = std::move(con);
2509 ~CurrentObjectSetter()
2511 currentObjectPath = "";
2512 currentConnection = {};
2514 CurrentObjectSetter(const CurrentObjectSetter&) = delete;
2515 CurrentObjectSetter(CurrentObjectSetter&&) = delete;
2516 void operator=(const CurrentObjectSetter&) = delete;
2517 void operator=(CurrentObjectSetter&&) = delete;
2521 DBusWrapper::ConnectionPtr connection;
2522 struct DestructorObject {
2523 std::vector<std::function<void()>> destructors;
2524 ~DestructorObject() {
2525 for (auto& a : destructors) a();
2529 std::unique_ptr<DestructorObject> destructorObject{ new DestructorObject() };
2530 static thread_local std::string currentObjectPath;
2531 static thread_local DBusWrapper::ConnectionPtr currentConnection;
2535 DBusWrapper::ConnectionPtr getDBusConnectionByType(ConnectionType tp);
2536 DBusWrapper::ConnectionPtr getDBusConnectionByName(const std::string& name);
2537 std::string getConnectionName(const DBusWrapper::ConnectionPtr&);
2542 template < size_t INDEX, typename... ARGS >
2543 inline auto get(DBus::ValueOrError< ARGS... >& v) -> decltype(std::get< INDEX >(v.getValues()))&
2545 return std::get< INDEX >(v.getValues());
2548 template < size_t INDEX, typename... ARGS >
2549 inline auto get(const DBus::ValueOrError< ARGS... >& v) -> decltype(std::get< INDEX >(v.getValues()))
2551 return std::get< INDEX >(v.getValues());
2555 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_DBUS_H