diff options
author | Jürgen Gehring <juergen.gehring@bmw.de> | 2015-07-29 00:04:02 -0700 |
---|---|---|
committer | Jürgen Gehring <juergen.gehring@bmw.de> | 2015-07-29 00:04:02 -0700 |
commit | db96446ece67ba1f495811e29838e8c7bc7984ff (patch) | |
tree | ad49d3368287caf7d201057989db4bd19e37fd0c /include/CommonAPI/DBus | |
parent | 49d0b428ca19852d49965f35328a314f22d88807 (diff) | |
download | genivi-common-api-dbus-runtime-db96446ece67ba1f495811e29838e8c7bc7984ff.tar.gz |
CommonAPI-D-Bus 3.1.33.1.3
Diffstat (limited to 'include/CommonAPI/DBus')
19 files changed, 477 insertions, 139 deletions
diff --git a/include/CommonAPI/DBus/CommonAPIDBus.hpp b/include/CommonAPI/DBus/CommonAPIDBus.hpp new file mode 100644 index 0000000..1be7770 --- /dev/null +++ b/include/CommonAPI/DBus/CommonAPIDBus.hpp @@ -0,0 +1,18 @@ +// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef COMMONAPI_DBUS_HPP_ +#define COMMONAPI_DBUS_HPP_ + +#ifndef COMMONAPI_INTERNAL_COMPILATION +#define COMMONAPI_INTERNAL_COMPILATION +#endif + +#include "DBusAddressTranslator.hpp" + +#undef COMMONAPI_INTERNAL_COMPILATION + +#endif // COMMONAPI_DBUS_HPP_ + diff --git a/include/CommonAPI/DBus/DBusAddressTranslator.hpp b/include/CommonAPI/DBus/DBusAddressTranslator.hpp index 7f11197..bbe1d75 100644 --- a/include/CommonAPI/DBus/DBusAddressTranslator.hpp +++ b/include/CommonAPI/DBus/DBusAddressTranslator.hpp @@ -3,6 +3,10 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +#if !defined (COMMONAPI_INTERNAL_COMPILATION) +#error "Only <CommonAPI/CommonAPI.hpp> can be included directly, this file may disappear or change contents." +#endif + #ifndef COMMONAPI_DBUS_ADDRESSTRANSLATOR_HPP_ #define COMMONAPI_DBUS_ADDRESSTRANSLATOR_HPP_ @@ -10,6 +14,7 @@ #include <memory> #include <mutex> +#include <CommonAPI/Types.hpp> #include <CommonAPI/Address.hpp> #include <CommonAPI/DBus/DBusAddress.hpp> #include <CommonAPI/DBus/DBusTypes.hpp> @@ -32,9 +37,15 @@ public: COMMONAPI_EXPORT bool translate(const DBusAddress &_key, CommonAPI::Address &_value); COMMONAPI_EXPORT void insert(const std::string &_address, - const std::string &_service, const std::string &_path, const std::string &_interface); + const std::string &_service, const std::string &_path, const std::string &_interface, const bool _objPathStartWithDigits = false); + + COMMONAPI_EXPORT DBusType_t getDBusBusType(const ConnectionId_t &_connectionId) const ; - COMMONAPI_EXPORT DBusType_t getDBusBusType() const; + /** + * @brief Returns whether or not org.freedesktop.DBus.Peer interface is used in a (valid) name mapping. + * @return true in case any (valid) mapping of org.freedesktop.DBus.Peer is present, otherwise false + */ + COMMONAPI_EXPORT bool isOrgFreedesktopDBusPeerMapped() const; private: COMMONAPI_EXPORT bool readConfiguration(); @@ -53,7 +64,9 @@ private: std::mutex mutex_; - DBusType_t dBusBusType_; + std::map<ConnectionId_t, DBusType_t> dbusTypes_; + + bool orgFreedesktopDBusPeerMapped_; }; } // namespace DBus diff --git a/include/CommonAPI/DBus/DBusAttribute.hpp b/include/CommonAPI/DBus/DBusAttribute.hpp index 3d9170d..50dea3b 100644 --- a/include/CommonAPI/DBus/DBusAttribute.hpp +++ b/include/CommonAPI/DBus/DBusAttribute.hpp @@ -138,7 +138,7 @@ public: const char *_changedEventName, _AttributeTypeArguments... arguments) : _AttributeType(_proxy, arguments...), - changedEvent_(_proxy, _changedEventName, this->setMethodSignature_, + changedEvent_(_proxy, _changedEventName, this->setMethodSignature_, this->getMethodName_, std::make_tuple(CommonAPI::Deployable<ValueType, ValueTypeDepl>(this->depl_))) { } diff --git a/include/CommonAPI/DBus/DBusConnection.hpp b/include/CommonAPI/DBus/DBusConnection.hpp index cce6296..97cb069 100644 --- a/include/CommonAPI/DBus/DBusConnection.hpp +++ b/include/CommonAPI/DBus/DBusConnection.hpp @@ -33,7 +33,7 @@ public: virtual ~DBusConnectionStatusEvent() {} protected: - virtual void onListenerAdded(const Listener& listener); + virtual void onListenerAdded(const Listener& listener, const Subscription subscription); // TODO: change to std::weak_ptr<DBusConnection> connection_; DBusConnection* dbusConnection_; @@ -130,6 +130,8 @@ public: COMMONAPI_EXPORT bool isDispatchReady(); COMMONAPI_EXPORT bool singleDispatch(); + COMMONAPI_EXPORT virtual bool hasDispatchThread(); + typedef std::tuple<std::string, std::string, std::string> DBusSignalMatchRuleTuple; typedef std::pair<uint32_t, std::string> DBusSignalMatchRuleMapping; typedef std::unordered_map<DBusSignalMatchRuleTuple, DBusSignalMatchRuleMapping> DBusSignalMatchRulesMap; @@ -164,6 +166,8 @@ public: COMMONAPI_EXPORT void initLibdbusObjectPathHandlerAfterConnect(); ::DBusHandlerResult onLibdbusObjectPathMessage(::DBusMessage* libdbusMessage); + COMMONAPI_EXPORT static DBusMessage convertToDBusMessage(::DBusPendingCall* _libdbusPendingCall, + CallStatus& _callStatus); COMMONAPI_EXPORT static void onLibdbusPendingCallNotifyThunk(::DBusPendingCall* libdbusPendingCall, void* userData); COMMONAPI_EXPORT static void onLibdbusDataCleanup(void* userData); @@ -242,12 +246,17 @@ public: > > timeoutMap_; - typedef std::pair<DBusMessageReplyAsyncHandler *, DBusMessage> MainloopTimeout_t; + typedef std::tuple< + DBusMessageReplyAsyncHandler *, + DBusMessage, + CommonAPI::CallStatus, + ::DBusPendingCall* + > MainloopTimeout_t; mutable std::list<MainloopTimeout_t> mainloopTimeouts_; mutable std::mutex enforceTimeoutMutex_; mutable std::condition_variable enforceTimeoutCondition_; - + mutable std::shared_ptr<std::thread> enforcerThread_; mutable std::mutex enforcerThreadMutex_; bool enforcerThreadCancelled_; diff --git a/include/CommonAPI/DBus/DBusDeployment.hpp b/include/CommonAPI/DBus/DBusDeployment.hpp index 21ad78a..dce9d21 100644 --- a/include/CommonAPI/DBus/DBusDeployment.hpp +++ b/include/CommonAPI/DBus/DBusDeployment.hpp @@ -21,16 +21,34 @@ namespace DBus { template<typename... _Types> struct VariantDeployment : CommonAPI::Deployment<_Types...> { - VariantDeployment(bool _isFreeDesktop, _Types*... _t) + VariantDeployment(bool _isDBus, _Types*... _t) : CommonAPI::Deployment<_Types...>(_t...), - isFreeDesktop_(_isFreeDesktop) { - } + isDBus_(_isDBus) {}; - bool isFreeDesktop_; + bool isDBus_; }; extern COMMONAPI_IMPORT_EXPORT VariantDeployment<> freedesktopVariant; +struct StringDeployment : CommonAPI::Deployment<> { + StringDeployment(bool _isObjectPath) + : isObjectPath_(_isObjectPath) {}; + + bool isObjectPath_; +}; + +template<typename... _Types> +struct StructDeployment : CommonAPI::Deployment<_Types...> { + StructDeployment(_Types*... t) + : CommonAPI::Deployment<_Types...>(t...) {}; +}; + +template<typename _ElementDepl> +struct ArrayDeployment : CommonAPI::ArrayDeployment<_ElementDepl> { + ArrayDeployment(_ElementDepl *_element) + : CommonAPI::ArrayDeployment<_ElementDepl>(_element) {} +}; + } // namespace DBus } // namespace CommonAPI diff --git a/include/CommonAPI/DBus/DBusEvent.hpp b/include/CommonAPI/DBus/DBusEvent.hpp index a3bfe01..3ce945c 100644 --- a/include/CommonAPI/DBus/DBusEvent.hpp +++ b/include/CommonAPI/DBus/DBusEvent.hpp @@ -24,6 +24,7 @@ namespace DBus { template <typename _Event, typename... _Arguments> class DBusEvent: public _Event, public DBusProxyConnection::DBusSignalHandler { public: + typedef typename _Event::Subscription Subscription; typedef typename _Event::Listener Listener; DBusEvent(DBusProxyBase &_proxy, @@ -31,6 +32,7 @@ public: std::tuple<_Arguments...> _arguments) : proxy_(_proxy), name_(_name), signature_(_signature), + getMethodName_(""), arguments_(_arguments) { interface_ = proxy_.getDBusAddress().getInterface(); @@ -44,9 +46,25 @@ public: : proxy_(_proxy), name_(_name), signature_(_signature), path_(_path), interface_(_interface), + getMethodName_(""), arguments_(_arguments) { } + DBusEvent(DBusProxyBase &_proxy, + const std::string &_name, + const std::string &_signature, + const std::string &_getMethodName, + std::tuple<_Arguments...> _arguments) + : proxy_(_proxy), + name_(_name), + signature_(_signature), + getMethodName_(_getMethodName), + arguments_(_arguments) { + + interface_ = proxy_.getDBusAddress().getInterface(); + path_ = proxy_.getDBusAddress().getObjectPath(); + } + virtual ~DBusEvent() { proxy_.removeSignalMemberHandler(subscription_, this); } @@ -54,14 +72,29 @@ public: virtual void onSignalDBusMessage(const DBusMessage &_message) { handleSignalDBusMessage(_message, typename make_sequence<sizeof...(_Arguments)>::type()); } + + virtual void onInitialValueSignalDBusMessage(const DBusMessage&_message, const uint32_t tag) { + handleSignalDBusMessage(tag, _message, typename make_sequence<sizeof...(_Arguments)>::type()); + } + protected: - virtual void onFirstListenerAdded(const Listener&) { - subscription_ = proxy_.addSignalMemberHandler( - path_, interface_, name_, signature_, this); + virtual void onFirstListenerAdded(const Listener& listener) { + subscription_ = proxy_.addSignalMemberHandler( + path_, interface_, name_, signature_, getMethodName_, this, false); + } + + virtual void onListenerAdded(const Listener& listener, const Subscription subscription) { + if ("" != getMethodName_) { + proxy_.getCurrentValueForSignalListener(getMethodName_, this, subscription); + } } virtual void onLastListenerRemoved(const Listener&) { proxy_.removeSignalMemberHandler(subscription_, this); + std::get<0>(subscription_) = ""; + std::get<1>(subscription_) = ""; + std::get<2>(subscription_) = ""; + std::get<3>(subscription_) = ""; } template<int ... _Indices> @@ -74,12 +107,23 @@ public: } } + template<int ... _Indices> + inline void handleSignalDBusMessage(const uint32_t tag, const DBusMessage &_message, index_sequence<_Indices...>) { + DBusInputStream input(_message); + if (DBusSerializableArguments< + _Arguments... + >::deserialize(input, std::get<_Indices>(arguments_)...)) { + this->notifySpecificListener(tag, std::get<_Indices>(arguments_)...); + } + } + DBusProxyBase &proxy_; std::string name_; std::string signature_; std::string path_; std::string interface_; + std::string getMethodName_; DBusProxyConnection::DBusSignalHandlerToken subscription_; std::tuple<_Arguments...> arguments_; diff --git a/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp b/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp index dc485cb..fd9237e 100644 --- a/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp +++ b/include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp @@ -15,16 +15,19 @@ namespace CommonAPI { namespace DBus { -template <typename _AttributeType> +template <typename _AttributeType, typename _AttributeDepl = EmptyDeployment> class DBusFreedesktopReadonlyAttribute: public _AttributeType { public: typedef typename _AttributeType::ValueType ValueType; + typedef _AttributeDepl ValueTypeDepl; typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback; - DBusFreedesktopReadonlyAttribute(DBusProxy &_proxy, const std::string &_interfaceName, const std::string &_propertyName) + DBusFreedesktopReadonlyAttribute(DBusProxy &_proxy, const std::string &_interfaceName, const std::string &_propertyName, + _AttributeDepl *_depl = nullptr) : proxy_(_proxy), interfaceName_(_interfaceName), - propertyName_(_propertyName) { + propertyName_(_propertyName), + depl_(_depl) { } void getValue(CommonAPI::CallStatus &_status, ValueType &_value, const CommonAPI::CallInfo *_info) const { @@ -78,6 +81,7 @@ protected: DBusProxy &proxy_; std::string interfaceName_; std::string propertyName_; + _AttributeDepl *depl_; }; template <typename _AttributeType> @@ -145,16 +149,15 @@ protected: std::string propertyName_; }; -template <typename _AttributeType> +template <typename _AttributeType, typename _AttributeDepl = EmptyDeployment> class DBusFreedesktopAttribute - : public DBusFreedesktopReadonlyAttribute<_AttributeType> { + : public DBusFreedesktopReadonlyAttribute<_AttributeType, _AttributeDepl> { public: typedef typename _AttributeType::ValueType ValueType; typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback; - typedef typename _AttributeType::ChangedEvent ChangedEvent; - DBusFreedesktopAttribute(DBusProxy &_proxy, const std::string &_interfaceName, const std::string &_propertyName) - : DBusFreedesktopReadonlyAttribute<_AttributeType>(_proxy, _interfaceName, _propertyName) { + DBusFreedesktopAttribute(DBusProxy &_proxy, const std::string &_interfaceName, const std::string &_propertyName, _AttributeDepl *_depl = nullptr) + : DBusFreedesktopReadonlyAttribute<_AttributeType, _AttributeDepl>(_proxy, _interfaceName, _propertyName, _depl) { } void setValue(const ValueType &_request, CommonAPI::CallStatus &_status, ValueType &_response, const CommonAPI::CallInfo *_info) { @@ -166,13 +169,13 @@ class DBusFreedesktopAttribute DBusSerializableArguments< > >::callMethodWithReply( - DBusFreedesktopReadonlyAttribute<_AttributeType>::proxy_, + DBusFreedesktopReadonlyAttribute<_AttributeType, _AttributeDepl>::proxy_, "org.freedesktop.DBus.Properties", "Set", "ssv", (_info ? _info : &defaultCallInfo), - DBusFreedesktopReadonlyAttribute<_AttributeType>::interfaceName_, - DBusFreedesktopReadonlyAttribute<_AttributeType>::propertyName_, + DBusFreedesktopReadonlyAttribute<_AttributeType, _AttributeDepl>::interfaceName_, + DBusFreedesktopReadonlyAttribute<_AttributeType, _AttributeDepl>::propertyName_, deployedVariant, _status); _response = _request; @@ -187,13 +190,13 @@ class DBusFreedesktopAttribute DBusSerializableArguments< > >::callMethodAsync( - DBusFreedesktopReadonlyAttribute<_AttributeType>::proxy_, + DBusFreedesktopReadonlyAttribute<_AttributeType, _AttributeDepl>::proxy_, "org.freedesktop.DBus.Properties", "Set", "ssv", (_info ? _info : &defaultCallInfo), - DBusFreedesktopReadonlyAttribute<_AttributeType>::interfaceName_, - DBusFreedesktopReadonlyAttribute<_AttributeType>::propertyName_, + DBusFreedesktopReadonlyAttribute<_AttributeType, _AttributeDepl>::interfaceName_, + DBusFreedesktopReadonlyAttribute<_AttributeType, _AttributeDepl>::propertyName_, deployedVariant, [_callback, deployedVariant](CommonAPI::CallStatus _status) { _callback(_status, deployedVariant.getValue().template get<ValueType>()); diff --git a/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp b/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp index 5c0bffa..bfe2493 100644 --- a/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp +++ b/include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp @@ -26,16 +26,16 @@ public: const std::shared_ptr<DBusClientId> &_clientId) = 0; }; -template <typename _StubClass, typename _AttributeType> +template <typename _StubClass, typename _AttributeType, typename _AttributeDepl = EmptyDeployment> class DBusGetFreedesktopAttributeStubDispatcher - : public virtual DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>, + : public virtual DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>, public virtual DBusGetFreedesktopAttributeStubDispatcherBase<_StubClass> { public: typedef DBusStubAdapterHelper<_StubClass> DBusStubAdapterHelperType; - typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::GetStubFunctor GetStubFunctor; + typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::GetStubFunctor GetStubFunctor; - DBusGetFreedesktopAttributeStubDispatcher(GetStubFunctor _getStubFunctor) - : DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>(_getStubFunctor, "v") { + DBusGetFreedesktopAttributeStubDispatcher(GetStubFunctor _getStubFunctor, _AttributeDepl *_depl = nullptr) + : DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>(_getStubFunctor, "v", _depl) { } virtual ~DBusGetFreedesktopAttributeStubDispatcher() {}; @@ -45,18 +45,19 @@ public: DBusOutputStream &_output, const std::shared_ptr<DBusClientId> &_clientId) { CommonAPI::Deployable<CommonAPI::Variant<_AttributeType>, VariantDeployment<>> deployedVariant( - (_stub.get()->*(DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::getStubFunctor_))(_clientId), &freedesktopVariant); + (_stub.get()->*(DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::getStubFunctor_))(_clientId), &freedesktopVariant); _output << deployedVariant; } protected: virtual bool sendAttributeValueReply(const DBusMessage &_message, const std::shared_ptr<_StubClass> &_stub, DBusStubAdapterHelperType &_helper) { - DBusMessage reply = _message.createMethodReturn(DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::signature_); + DBusMessage reply = _message.createMethodReturn(DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::signature_); + VariantDeployment<_AttributeDepl> actualDepl(true, DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::depl_); std::shared_ptr<DBusClientId> clientId = std::make_shared<DBusClientId>(std::string(_message.getSender())); - CommonAPI::Deployable<CommonAPI::Variant<_AttributeType>, VariantDeployment<>> deployedVariant( - (_stub.get()->*(DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::getStubFunctor_))(clientId), &freedesktopVariant); + CommonAPI::Deployable<CommonAPI::Variant<_AttributeType>, VariantDeployment<_AttributeDepl>> deployedVariant( + (_stub.get()->*(DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::getStubFunctor_))(clientId), &actualDepl); DBusOutputStream output(reply); output << deployedVariant; @@ -66,13 +67,13 @@ protected: } }; -template <typename _StubClass, typename _AttributeType> +template <typename _StubClass, typename _AttributeType, typename _AttributeDepl = EmptyDeployment> class DBusSetFreedesktopAttributeStubDispatcher - : public virtual DBusGetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>, - public virtual DBusSetAttributeStubDispatcher<_StubClass, _AttributeType> { + : public virtual DBusGetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>, + public virtual DBusSetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl> { public: - typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::GetStubFunctor GetStubFunctor; - typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::DBusStubAdapterHelperType DBusStubAdapterHelperType; + typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::GetStubFunctor GetStubFunctor; + typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::DBusStubAdapterHelperType DBusStubAdapterHelperType; typedef typename DBusStubAdapterHelperType::RemoteEventHandlerType RemoteEventHandlerType; typedef bool (RemoteEventHandlerType::*OnRemoteSetFunctor)(std::shared_ptr<CommonAPI::ClientId>, _AttributeType); typedef void (RemoteEventHandlerType::*OnRemoteChangedFunctor)(); @@ -80,16 +81,17 @@ public: DBusSetFreedesktopAttributeStubDispatcher( GetStubFunctor _getStubFunctor, OnRemoteSetFunctor _onRemoteSetFunctor, - OnRemoteChangedFunctor _onRemoteChangedFunctor) - : DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>(_getStubFunctor, "v"), - DBusGetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>(_getStubFunctor), - DBusSetAttributeStubDispatcher<_StubClass, _AttributeType>(_getStubFunctor, _onRemoteSetFunctor, _onRemoteChangedFunctor, "v") { + OnRemoteChangedFunctor _onRemoteChangedFunctor, + _AttributeDepl * _depl = nullptr) + : DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>(_getStubFunctor, "v", _depl), + DBusGetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>(_getStubFunctor, _depl), + DBusSetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>(_getStubFunctor, _onRemoteSetFunctor, _onRemoteChangedFunctor, "v", _depl) { } virtual ~DBusSetFreedesktopAttributeStubDispatcher() {}; protected: - virtual _AttributeType retreiveAttributeValue(const DBusMessage &_message, bool &_error) { + virtual _AttributeType retrieveAttributeValue(const DBusMessage &_message, bool &_error) { std::string interfaceName, attributeName; DBusInputStream input(_message); CommonAPI::Deployable<CommonAPI::Variant<_AttributeType>, VariantDeployment<>> deployedVariant(&freedesktopVariant); @@ -102,28 +104,29 @@ protected: } }; -template <typename _StubClass, typename _AttributeType> +template <typename _StubClass, typename _AttributeType, typename _AttributeDepl = EmptyDeployment> class DBusSetFreedesktopObservableAttributeStubDispatcher - : public virtual DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>, - public virtual DBusSetObservableAttributeStubDispatcher<_StubClass, _AttributeType> { + : public virtual DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>, + public virtual DBusSetObservableAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl> { public: - typedef typename DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>::DBusStubAdapterHelperType DBusStubAdapterHelperType; + typedef typename DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::DBusStubAdapterHelperType DBusStubAdapterHelperType; typedef typename DBusStubAdapterHelperType::StubAdapterType StubAdapterType; - typedef typename DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>::GetStubFunctor GetStubFunctor; - typedef typename DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>::OnRemoteSetFunctor OnRemoteSetFunctor; - typedef typename DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>::OnRemoteChangedFunctor OnRemoteChangedFunctor; + typedef typename DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::GetStubFunctor GetStubFunctor; + typedef typename DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::OnRemoteSetFunctor OnRemoteSetFunctor; + typedef typename DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>::OnRemoteChangedFunctor OnRemoteChangedFunctor; typedef void (StubAdapterType::*FireChangedFunctor)(const _AttributeType&); DBusSetFreedesktopObservableAttributeStubDispatcher( GetStubFunctor _getStubFunctor, OnRemoteSetFunctor _onRemoteSetFunctor, OnRemoteChangedFunctor _onRemoteChangedFunctor, - FireChangedFunctor _fireChangedFunctor) - : DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>(_getStubFunctor, "v"), - DBusGetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>(_getStubFunctor), - DBusSetAttributeStubDispatcher<_StubClass, _AttributeType>(_getStubFunctor, _onRemoteSetFunctor, _onRemoteChangedFunctor, "v"), - DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>(_getStubFunctor, _onRemoteSetFunctor, _onRemoteChangedFunctor), - DBusSetObservableAttributeStubDispatcher<_StubClass, _AttributeType>(_getStubFunctor, _onRemoteSetFunctor, _onRemoteChangedFunctor, _fireChangedFunctor, "v") { + FireChangedFunctor _fireChangedFunctor, + _AttributeDepl *_depl = nullptr) + : DBusGetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>(_getStubFunctor, "v", _depl), + DBusGetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>(_getStubFunctor, _depl), + DBusSetAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>(_getStubFunctor, _onRemoteSetFunctor, _onRemoteChangedFunctor, "v", _depl), + DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>(_getStubFunctor, _onRemoteSetFunctor, _onRemoteChangedFunctor, _depl), + DBusSetObservableAttributeStubDispatcher<_StubClass, _AttributeType, _AttributeDepl>(_getStubFunctor, _onRemoteSetFunctor, _onRemoteChangedFunctor, _fireChangedFunctor, "v", _depl) { } }; diff --git a/include/CommonAPI/DBus/DBusInputStream.hpp b/include/CommonAPI/DBus/DBusInputStream.hpp index 389cb68..4f00cec 100644 --- a/include/CommonAPI/DBus/DBusInputStream.hpp +++ b/include/CommonAPI/DBus/DBusInputStream.hpp @@ -65,8 +65,38 @@ public: COMMONAPI_EXPORT InputStream &readValue(std::string &_value, const EmptyDeployment *_depl); + COMMONAPI_EXPORT InputStream &readValue(std::string &_value, const CommonAPI::DBus::StringDeployment* _depl) { + return readValue(_value, static_cast<EmptyDeployment *>(nullptr)); + } + COMMONAPI_EXPORT InputStream &readValue(Version &_value, const EmptyDeployment *_depl); + COMMONAPI_EXPORT void beginReadMapOfSerializableStructs() { + uint32_t itsSize; + _readValue(itsSize); + pushSize(itsSize); + align(8); /* correct alignment for first DICT_ENTRY */ + pushPosition(); + } + + COMMONAPI_EXPORT bool readMapCompleted() { + return (sizes_.top() <= (current_ - positions_.top())); + } + + COMMONAPI_EXPORT void endReadMapOfSerializableStructs() { + (void)popSize(); + (void)popPosition(); + } + + COMMONAPI_EXPORT InputStream &skipMap() { + uint32_t itsSize; + _readValue(itsSize); + align(8); /* skip padding (if any) */ + assert(itsSize <= (sizes_.top() + positions_.top() - current_)); + _readRaw(itsSize); + return (*this); + } + template<class _Deployment, typename _Base> COMMONAPI_EXPORT InputStream &readValue(Enumeration<_Base> &_value, const _Deployment *_depl) { _Base tmpValue; @@ -127,7 +157,7 @@ public: Variant<_Types...>, _Types... >::visit(visitor, _value); } - if (_depl != nullptr && _depl->isFreeDesktop_) { + if (_depl != nullptr && _depl->isDBus_) { // Read signature uint8_t signatureLength; readValue(signatureLength, static_cast<EmptyDeployment *>(nullptr)); @@ -195,7 +225,7 @@ public: _value.clear(); while (sizes_.top() > current_ - positions_.top()) { _ElementType itsElement; - readValue(itsElement, _depl->elementDepl_); + readValue(itsElement, (_depl ? _depl->elementDepl_ : nullptr)); if (hasError()) { break; @@ -264,8 +294,8 @@ public: _ValueType itsValue; align(8); - readValue(itsKey, _depl->key_); - readValue(itsValue, _depl->value_); + readValue(itsKey, (_depl ? _depl->key_ : nullptr)); + readValue(itsValue, (_depl ? _depl->value_ : nullptr)); if (hasError()) { break; diff --git a/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp b/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp index d520034..0f3dd24 100644 --- a/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp +++ b/include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp @@ -55,14 +55,16 @@ class DBusInstanceAvailabilityStatusChangedEvent: DBusObjectManagerStub::getInterfaceName(), "InterfacesAdded", "oa{sa{sv}}", - this); + this, + false); interfacesRemovedSubscription_ = proxy_.addSignalMemberHandler( proxy_.getDBusAddress().getObjectPath(), DBusObjectManagerStub::getInterfaceName(), "InterfacesRemoved", "oas", - this); + this, + false); } virtual void onLastListenerRemoved(const Listener&) { @@ -74,21 +76,23 @@ class DBusInstanceAvailabilityStatusChangedEvent: inline void onInterfacesAddedSignal(const DBusMessage &_message) { DBusInputStream dbusInputStream(_message); std::string dbusObjectPath; + std::string dbusInterfaceName; DBusInterfacesAndPropertiesDict dbusInterfacesAndPropertiesDict; dbusInputStream >> dbusObjectPath; assert(!dbusInputStream.hasError()); - dbusInputStream >> dbusInterfacesAndPropertiesDict; - assert(!dbusInputStream.hasError()); - - for (const auto& dbusInterfaceIterator : dbusInterfacesAndPropertiesDict) { - const std::string& dbusInterfaceName = dbusInterfaceIterator.first; - + dbusInputStream.beginReadMapOfSerializableStructs(); + while (!dbusInputStream.readMapCompleted()) { + dbusInputStream.align(8); + dbusInputStream >> dbusInterfaceName; + dbusInputStream.skipMap(); + assert(!dbusInputStream.hasError()); if(dbusInterfaceName == observedInterfaceName_) { notifyInterfaceStatusChanged(dbusObjectPath, dbusInterfaceName, AvailabilityStatus::AVAILABLE); } } + dbusInputStream.endReadMapOfSerializableStructs(); } inline void onInterfacesRemovedSignal(const DBusMessage &_message) { diff --git a/include/CommonAPI/DBus/DBusMainLoopContext.hpp b/include/CommonAPI/DBus/DBusMainLoopContext.hpp index 9230cd2..27428db 100644 --- a/include/CommonAPI/DBus/DBusMainLoopContext.hpp +++ b/include/CommonAPI/DBus/DBusMainLoopContext.hpp @@ -47,6 +47,10 @@ class DBusWatch: public Watch { const pollfd& getAssociatedFileDescriptor(); +#ifdef WIN32 + const HANDLE& getAssociatedEvent(); +#endif + const std::vector<DispatchSource*>& getDependentDispatchSources(); void addDependentDispatchSource(DispatchSource* dispatchSource); private: @@ -57,6 +61,10 @@ class DBusWatch: public Watch { std::vector<DispatchSource*> dependentDispatchSources_; std::weak_ptr<MainLoopContext> mainLoopContext_; + +#ifdef WIN32 + HANDLE wsaEvent_; +#endif }; diff --git a/include/CommonAPI/DBus/DBusOutputStream.hpp b/include/CommonAPI/DBus/DBusOutputStream.hpp index b0bdd22..93afca2 100644 --- a/include/CommonAPI/DBus/DBusOutputStream.hpp +++ b/include/CommonAPI/DBus/DBusOutputStream.hpp @@ -111,6 +111,10 @@ public: return writeString(_value.c_str(), _value.length()); } + COMMONAPI_EXPORT OutputStream &writeValue(const std::string &_value, const CommonAPI::DBus::StringDeployment* _depl) { + return writeString(_value.c_str(), _value.length()); + } + COMMONAPI_EXPORT OutputStream &writeValue(const Version &_value, const EmptyDeployment *_depl = nullptr) { align(8); writeValue(_value.Major, _depl); @@ -168,7 +172,7 @@ public: template<typename _Deployment, typename... _Types> COMMONAPI_EXPORT OutputStream &writeValue(const Variant<_Types...> &_value, const _Deployment *_depl = nullptr) { - if (_depl != nullptr && _depl->isFreeDesktop_) { + if (_depl != nullptr && _depl->isDBus_) { align(1); } else { align(8); @@ -223,7 +227,7 @@ public: pushPosition(); // Start of vector data for (auto i : _value) { - writeValue(i, _depl->elementDepl_); + writeValue(i, (_depl ? _depl->elementDepl_ : nullptr)); if (hasError()) { break; } @@ -274,8 +278,8 @@ public: for (auto v : _value) { align(8); - writeValue(v.first, _depl->key_); - writeValue(v.second, _depl->value_); + writeValue(v.first, (_depl ? _depl->key_ : nullptr)); + writeValue(v.second, (_depl ? _depl->value_ : nullptr)); if (hasError()) { return (*this); @@ -289,6 +293,15 @@ public: } /** + * Fills the stream with 0-bytes to make the next value be aligned to the boundary given. + * This means that as many 0-bytes are written to the buffer as are necessary + * to make the next value start with the given alignment. + * + * @param alignBoundary The byte-boundary to which the next value should be aligned. + */ + COMMONAPI_EXPORT void align(const size_t _boundary); + + /** * Writes the data that was buffered within this #DBusOutputMessageStream to the #DBusMessage that was given to the constructor. Each call to flush() * will completely override the data that currently is contained in the #DBusMessage. The data that is buffered in this #DBusOutputMessageStream is * not deleted by calling flush(). @@ -297,6 +310,22 @@ public: COMMONAPI_EXPORT bool hasError() const; + // Helper for serializing Freedesktop properties + COMMONAPI_EXPORT void beginWriteMap() { + align(sizeof(uint32_t)); + pushPosition(); + _writeValue(static_cast<uint32_t>(0)); // Placeholder + + align(8); + pushPosition(); // Start of map data + } + + COMMONAPI_EXPORT void endWriteMap() { + // Write number of written bytes to placeholder position + const uint32_t length = getPosition() - popPosition(); + _writeValueAt(popPosition(), length); + } + private: COMMONAPI_EXPORT size_t getPosition(); COMMONAPI_EXPORT void pushPosition(); @@ -361,15 +390,6 @@ private: COMMONAPI_EXPORT DBusOutputStream &writeString(const char *_data, const uint32_t &_length); /** - * Fills the stream with 0-bytes to make the next value be aligned to the boundary given. - * This means that as many 0-bytes are written to the buffer as are necessary - * to make the next value start with the given alignment. - * - * @param alignBoundary The byte-boundary to which the next value should be aligned. - */ - COMMONAPI_EXPORT void align(const size_t _boundary); - - /** * Takes sizeInByte characters, starting from the character which val points to, and stores them for later writing. * When calling flush(), all values that were written to this stream are copied into the payload of the #DBusMessage. * diff --git a/include/CommonAPI/DBus/DBusProxy.hpp b/include/CommonAPI/DBus/DBusProxy.hpp index 058a681..2f8a89c 100644 --- a/include/CommonAPI/DBus/DBusProxy.hpp +++ b/include/CommonAPI/DBus/DBusProxy.hpp @@ -30,7 +30,7 @@ class DBusProxyStatusEvent virtual ~DBusProxyStatusEvent() {} protected: - virtual void onListenerAdded(const Listener& listener); + virtual void onListenerAdded(const Listener& listener, const Subscription subscription); DBusProxy* dbusProxy_; }; @@ -62,14 +62,61 @@ public: COMMONAPI_EXPORT void init(); + COMMONAPI_EXPORT virtual DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler( + const std::string &objectPath, + const std::string &interfaceName, + const std::string &signalName, + const std::string &signalSignature, + DBusProxyConnection::DBusSignalHandler *dbusSignalHandler, + const bool justAddFilter); + + COMMONAPI_EXPORT virtual DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler( + const std::string &objectPath, + const std::string &interfaceName, + const std::string &signalName, + const std::string &signalSignature, + const std::string &getMethodName, + DBusProxyConnection::DBusSignalHandler *dbusSignalHandler, + const bool justAddFilter); + + COMMONAPI_EXPORT virtual bool removeSignalMemberHandler( + const DBusProxyConnection::DBusSignalHandlerToken &_dbusSignalHandlerToken, + const DBusProxyConnection::DBusSignalHandler *_dbusSignalHandler = NULL); + + COMMONAPI_EXPORT virtual void getCurrentValueForSignalListener( + const std::string &getMethodName, + DBusProxyConnection::DBusSignalHandler *dbusSignalHandler, + const uint32_t subscription); + private: + typedef std::tuple< + const std::string, + const std::string, + const std::string, + const std::string, + const std::string, + DBusProxyConnection::DBusSignalHandler*, + const bool, + bool + > SignalMemberHandlerTuple; + COMMONAPI_EXPORT DBusProxy(const DBusProxy &) = delete; COMMONAPI_EXPORT void onDBusServiceInstanceStatus(const AvailabilityStatus& availabilityStatus); + COMMONAPI_EXPORT void signalMemberCallback(const CallStatus dbusMessageCallStatus, + const DBusMessage& dbusMessage, + DBusProxyConnection::DBusSignalHandler* dbusSignalHandlers, + const uint32_t tag); + COMMONAPI_EXPORT void signalInitialValueCallback(const CallStatus dbusMessageCallStatus, + const DBusMessage& dbusMessage, + DBusProxyConnection::DBusSignalHandler* dbusSignalHandlers, + const uint32_t tag); + COMMONAPI_EXPORT void addSignalMemberHandlerToQueue(SignalMemberHandlerTuple& _signalMemberHandler); DBusProxyStatusEvent dbusProxyStatusEvent_; DBusServiceRegistry::DBusServiceSubscription dbusServiceRegistrySubscription_; AvailabilityStatus availabilityStatus_; + mutable std::mutex availabilityStatusMutex_; DBusReadonlyAttribute<InterfaceVersionAttribute> interfaceVersionAttribute_; @@ -77,6 +124,10 @@ private: mutable std::mutex availabilityMutex_; mutable std::condition_variable availabilityCondition_; + + std::list<SignalMemberHandlerTuple> signalMemberHandlerQueue_; + CallInfo signalMemberHandlerInfo_; + mutable std::mutex signalMemberHandlerQueueMutex_; }; diff --git a/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp b/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp new file mode 100644 index 0000000..9c706ca --- /dev/null +++ b/include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp @@ -0,0 +1,68 @@ +// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#if !defined (COMMONAPI_INTERNAL_COMPILATION) +#error "Only <CommonAPI/CommonAPI.hpp> can be included directly, this file may disappear or change contents." +#endif + +#ifndef COMMONAPI_DBUS_DBUSPROXYASYNCSIGNALMEMBERCALLBACKHANDLER_HPP_ +#define COMMONAPI_DBUS_DBUSPROXYASYNCSIGNALMEMBERCALLBACKHANDLER_HPP_ + +#include <functional> +#include <future> +#include <memory> + +//#include <CommonAPI/DBus/DBusHelper.hpp> +#include <CommonAPI/DBus/DBusMessage.hpp> +#include <CommonAPI/DBus/DBusProxyConnection.hpp> + +namespace CommonAPI { +namespace DBus { + +class DBusProxyAsyncSignalMemberCallbackHandler: public DBusProxyConnection::DBusMessageReplyAsyncHandler { + public: + typedef std::function<void(CallStatus, DBusMessage, DBusProxyConnection::DBusSignalHandler*, int)> FunctionType; + + static std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler> create( + FunctionType& callback, DBusProxyConnection::DBusSignalHandler* dbusSignalHandler, + const int tag) { + return std::unique_ptr<DBusProxyConnection::DBusMessageReplyAsyncHandler>( + new DBusProxyAsyncSignalMemberCallbackHandler(std::move(callback), dbusSignalHandler, tag)); + } + + DBusProxyAsyncSignalMemberCallbackHandler() = delete; + DBusProxyAsyncSignalMemberCallbackHandler(FunctionType&& callback, + DBusProxyConnection::DBusSignalHandler* dbusSignalHandler, + const int tag): + callback_(std::move(callback)), dbusSignalHandler_(dbusSignalHandler), tag_(tag) { + } + virtual ~DBusProxyAsyncSignalMemberCallbackHandler() {} + + virtual std::future<CallStatus> getFuture() { + return promise_.get_future(); + } + + virtual void onDBusMessageReply(const CallStatus& dbusMessageCallStatus, const DBusMessage& dbusMessage) { + promise_.set_value(handleDBusMessageReply(dbusMessageCallStatus, dbusMessage)); + } + + private: + inline CallStatus handleDBusMessageReply(const CallStatus dbusMessageCallStatus, const DBusMessage& dbusMessage) const { + CallStatus callStatus = dbusMessageCallStatus; + + callback_(callStatus, dbusMessage, dbusSignalHandler_, tag_); + return callStatus; + } + + std::promise<CallStatus> promise_; + const FunctionType callback_; + DBusProxyConnection::DBusSignalHandler* dbusSignalHandler_; + const int tag_; +}; + +} // namespace DBus +} // namespace CommonAPI + +#endif // COMMONAPI_DBUS_DBUSPROXYASYNCSIGNALMEMBERCALLBACKHANDLER_HPP_ diff --git a/include/CommonAPI/DBus/DBusProxyBase.hpp b/include/CommonAPI/DBus/DBusProxyBase.hpp index 85c746c..970035f 100644 --- a/include/CommonAPI/DBus/DBusProxyBase.hpp +++ b/include/CommonAPI/DBus/DBusProxyBase.hpp @@ -39,27 +39,35 @@ public: COMMONAPI_EXPORT DBusMessage createMethodCall(const std::string &_method, const std::string &_signature = "") const; - COMMONAPI_EXPORT DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler( - const std::string& signalName, - const std::string& signalSignature, - DBusProxyConnection::DBusSignalHandler* dbusSignalHandler, - const bool justAddFilter = false); + COMMONAPI_EXPORT virtual DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler( + const std::string &objectPath, + const std::string &interfaceName, + const std::string &signalName, + const std::string &signalSignature, + DBusProxyConnection::DBusSignalHandler *dbusSignalHandler, + const bool justAddFilter); - COMMONAPI_EXPORT DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler( + COMMONAPI_EXPORT virtual DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler( const std::string &objectPath, const std::string &interfaceName, const std::string &signalName, const std::string &signalSignature, + const std::string &getMethodName, DBusProxyConnection::DBusSignalHandler *dbusSignalHandler, - const bool justAddFilter = false); + const bool justAddFilter); + + COMMONAPI_EXPORT virtual bool removeSignalMemberHandler( + const DBusProxyConnection::DBusSignalHandlerToken &_dbusSignalHandlerToken, + const DBusProxyConnection::DBusSignalHandler *_dbusSignalHandler = NULL); - COMMONAPI_EXPORT bool removeSignalMemberHandler( - const DBusProxyConnection::DBusSignalHandlerToken &_token, - const DBusProxyConnection::DBusSignalHandler *_handler = NULL); + COMMONAPI_EXPORT virtual void getCurrentValueForSignalListener( + const std::string &getMethodName, + DBusProxyConnection::DBusSignalHandler *dbusSignalHandler, + const uint32_t subscription) {} COMMONAPI_EXPORT virtual void init() = 0; - private: + protected: COMMONAPI_EXPORT DBusProxyBase(const DBusProxyBase &) = delete; DBusAddress dbusAddress_; diff --git a/include/CommonAPI/DBus/DBusProxyConnection.hpp b/include/CommonAPI/DBus/DBusProxyConnection.hpp index cbef54d..10c2ea4 100644 --- a/include/CommonAPI/DBus/DBusProxyConnection.hpp +++ b/include/CommonAPI/DBus/DBusProxyConnection.hpp @@ -51,6 +51,7 @@ class DBusProxyConnection { public: virtual ~DBusSignalHandler() {} virtual void onSignalDBusMessage(const DBusMessage&) = 0; + virtual void onInitialValueSignalDBusMessage(const DBusMessage&, const uint32_t) {}; }; // objectPath, interfaceName, interfaceMemberName, interfaceMemberSignature @@ -119,6 +120,8 @@ class DBusProxyConnection { virtual void setObjectPathMessageHandler(DBusObjectPathMessageHandler) = 0; virtual bool isObjectPathMessageHandlerSet() = 0; + + virtual bool hasDispatchThread() = 0; }; } // namespace DBus diff --git a/include/CommonAPI/DBus/DBusProxyHelper.hpp b/include/CommonAPI/DBus/DBusProxyHelper.hpp index 516d923..4a2748b 100644 --- a/include/CommonAPI/DBus/DBusProxyHelper.hpp +++ b/include/CommonAPI/DBus/DBusProxyHelper.hpp @@ -43,11 +43,11 @@ struct DBusProxyHelper<_In<DBusInputStream, DBusOutputStream, _InArgs...>, const _InArgs&... _in, CommonAPI::CallStatus &_status) { - if (_proxy.isAvailableBlocking()) { + if (_proxy.isAvailable()) { DBusMessage message = _proxy.createMethodCall(_method, _signature); if (sizeof...(_InArgs) > 0) { DBusOutputStream output(message); - if (DBusSerializableArguments<_InArgs...>::serialize(output, _in...)) { + if (!DBusSerializableArguments<_InArgs...>::serialize(output, _in...)) { _status = CallStatus::OUT_OF_MEMORY; return; } @@ -106,7 +106,7 @@ struct DBusProxyHelper<_In<DBusInputStream, DBusOutputStream, _InArgs...>, const _InArgs&... _in, CommonAPI::CallStatus &_status, _OutArgs&... _out) { - if (_proxy.isAvailableBlocking()) { + if (_proxy.isAvailable()) { DBusMessage message = DBusMessage::createMethodCall(_address, _method, _signature); callMethodWithReply(_proxy, message, _info, _in..., _status, _out...); } else { @@ -142,7 +142,7 @@ struct DBusProxyHelper<_In<DBusInputStream, DBusOutputStream, _InArgs...>, const _InArgs&... _in, CommonAPI::CallStatus &_status, _OutArgs&... _out) { - if (_proxy.isAvailableBlocking()) { + if (_proxy.isAvailable()) { DBusMessage message = _proxy.createMethodCall(_method, _signature); callMethodWithReply(_proxy, message, _info, _in..., _status, _out...); } else { diff --git a/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp b/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp index 730a5c7..90efba5 100644 --- a/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp +++ b/include/CommonAPI/DBus/DBusStubAdapterHelper.hpp @@ -193,7 +193,7 @@ class DBusStubAdapterHelper: public virtual DBusStubAdapter { DBusMessage dbusMessageReply = dbusMessage.createMethodReturn("a{sv}"); DBusOutputStream dbusOutputStream(dbusMessageReply); - dbusOutputStream.beginWriteVectorOfSerializableStructs(); + dbusOutputStream.beginWriteMap(); std::shared_ptr<DBusClientId> clientId = std::make_shared<DBusClientId>(std::string(dbusMessage.getSender())); for(auto attributeDispatcherIterator = getStubAttributeTable().begin(); attributeDispatcherIterator != getStubAttributeTable().end(); attributeDispatcherIterator++) { @@ -202,12 +202,13 @@ class DBusStubAdapterHelper: public virtual DBusStubAdapter { if (stub_) { StubDispatcher* getterDispatcher = static_cast<StubDispatcher*>(attributeDispatcherIterator->second.getter); assert(getterDispatcher != NULL); // all attributes have at least a getter + dbusOutputStream.align(8); dbusOutputStream << attributeDispatcherIterator->first; getterDispatcher->appendGetAllReply(dbusMessage, stub_, *this, dbusOutputStream); } } - dbusOutputStream.endWriteVector(); + dbusOutputStream.endWriteMap(); dbusOutputStream.flush(); return getDBusConnection()->sendDBusMessage(dbusMessageReply); @@ -287,59 +288,75 @@ struct DBusStubSignalHelper<_In<DBusInputStream, DBusOutputStream, _InArgs...>> } }; -template< class, class > +template< class, class, class > class DBusMethodStubDispatcher; template < typename _StubClass, - template <class...> class _In, class... _InArgs> -class DBusMethodStubDispatcher<_StubClass, _In<_InArgs...> >: public DBusStubAdapterHelper<_StubClass>::StubDispatcher { + template <class...> class _In, class... _InArgs, + template <class...> class _DeplIn, class... _DeplInArgs> + +class DBusMethodStubDispatcher<_StubClass, _In<_InArgs...>, _DeplIn<_DeplInArgs...> >: public DBusStubAdapterHelper<_StubClass>::StubDispatcher { public: typedef DBusStubAdapterHelper<_StubClass> DBusStubAdapterHelperType; typedef void (_StubClass::*_StubFunctor)(std::shared_ptr<CommonAPI::ClientId>, _InArgs...); - DBusMethodStubDispatcher(_StubFunctor stubFunctor): + DBusMethodStubDispatcher(_StubFunctor stubFunctor, std::tuple<_DeplInArgs*...> _in): stubFunctor_(stubFunctor) { + initialize(typename make_sequence_range<sizeof...(_DeplInArgs), 0>::type(), _in); } bool dispatchDBusMessage(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper) { - return handleDBusMessage(dbusMessage, stub, dbusStubAdapterHelper, typename make_sequence<sizeof...(_InArgs)>::type()); + return handleDBusMessage(dbusMessage, stub, dbusStubAdapterHelper, typename make_sequence_range<sizeof...(_InArgs), 0>::type()); } private: + template <int... _DeplInArgIndices> + inline void initialize(index_sequence<_DeplInArgIndices...>, std::tuple<_DeplInArgs*...> &_in) { + in_ = std::make_tuple(std::get<_DeplInArgIndices>(_in)...); + } + template <int... _InArgIndices> inline bool handleDBusMessage(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper, - index_sequence<_InArgIndices...>) const { - std::tuple<_InArgs...> argTuple; + index_sequence<_InArgIndices...>) { if (sizeof...(_InArgs) > 0) { DBusInputStream dbusInputStream(dbusMessage); - const bool success = DBusSerializableArguments<_InArgs...>::deserialize(dbusInputStream, std::get<_InArgIndices>(argTuple)...); + const bool success = DBusSerializableArguments<CommonAPI::Deployable<_InArgs, _DeplInArgs>...>::deserialize(dbusInputStream, std::get<_InArgIndices>(in_)...); if (!success) return false; } std::shared_ptr<DBusClientId> clientId = std::make_shared<DBusClientId>(std::string(dbusMessage.getSender())); - (stub.get()->*stubFunctor_)(clientId, std::move(std::get<_InArgIndices>(argTuple))...); + (stub.get()->*stubFunctor_)(clientId, std::move(std::get<_InArgIndices>(in_).getValue())...); return true; } _StubFunctor stubFunctor_; + std::tuple<CommonAPI::Deployable<_InArgs, _DeplInArgs>...> in_; }; -template< class, class, class> +template< class, class, class, class, class> class DBusMethodWithReplyStubDispatcher; template < typename _StubClass, template <class...> class _In, class... _InArgs, - template <class...> class _Out, class... _OutArgs> -class DBusMethodWithReplyStubDispatcher<_StubClass, _In<_InArgs...>, _Out<_OutArgs...> >: + template <class...> class _Out, class... _OutArgs, + template <class...> class _DeplIn, class... _DeplInArgs, + template <class...> class _DeplOut, class... _DeplOutArgs> + +class DBusMethodWithReplyStubDispatcher< + _StubClass, + _In<_InArgs...>, + _Out<_OutArgs...>, + _DeplIn<_DeplInArgs...>, + _DeplOut<_DeplOutArgs...> >: public DBusStubAdapterHelper<_StubClass>::StubDispatcher { public: typedef DBusStubAdapterHelper<_StubClass> DBusStubAdapterHelperType; @@ -347,38 +364,53 @@ class DBusMethodWithReplyStubDispatcher<_StubClass, _In<_InArgs...>, _Out<_OutAr typedef void (_StubClass::*_StubFunctor)( std::shared_ptr<CommonAPI::ClientId>, _InArgs..., ReplyType_t); - DBusMethodWithReplyStubDispatcher(_StubFunctor stubFunctor, const char* dbusReplySignature, std::tuple<_InArgs..., _OutArgs...> _args): + DBusMethodWithReplyStubDispatcher(_StubFunctor stubFunctor, + const char* dbusReplySignature, + std::tuple<_DeplInArgs*...> _inDepArgs, + std::tuple<_DeplOutArgs*...> _outDepArgs): stubFunctor_(stubFunctor), dbusReplySignature_(dbusReplySignature), - args_(_args), - currentCall_(0) { + out_(_outDepArgs), + currentCall_(0) { + + initialize(typename make_sequence_range<sizeof...(_DeplInArgs), 0>::type(), _inDepArgs); + } - bool dispatchDBusMessage(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper) { + bool dispatchDBusMessage(const DBusMessage& dbusMessage, + const std::shared_ptr<_StubClass>& stub, + DBusStubAdapterHelperType& dbusStubAdapterHelper) { connection_ = dbusStubAdapterHelper.getDBusConnection(); return handleDBusMessage( dbusMessage, stub, dbusStubAdapterHelper, typename make_sequence_range<sizeof...(_InArgs), 0>::type(), - typename make_sequence_range<sizeof...(_OutArgs), sizeof...(_InArgs)>::type(), args_); + typename make_sequence_range<sizeof...(_OutArgs), 0>::type()); } - bool sendReply(CommonAPI::CallId_t _call, std::tuple<_OutArgs...> args = std::make_tuple()) { + bool sendReply(CommonAPI::CallId_t _call, + std::tuple<CommonAPI::Deployable<_OutArgs, _DeplOutArgs>...> args = std::make_tuple()) { return sendReplyInternal(_call, typename make_sequence_range<sizeof...(_OutArgs), 0>::type(), args); } private: + + template <int... _DeplInArgIndices> + inline void initialize(index_sequence<_DeplInArgIndices...>, std::tuple<_DeplInArgs*...> &_in) { + in_ = std::make_tuple(std::get<_DeplInArgIndices>(_in)...); + } + + template <int... _InArgIndices, int... _OutArgIndices> inline bool handleDBusMessage(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper, index_sequence<_InArgIndices...>, - index_sequence<_OutArgIndices...>, - std::tuple<_InArgs..., _OutArgs...> argTuple) { - if (sizeof...(_InArgs) > 0) { + index_sequence<_OutArgIndices...>) { + if (sizeof...(_DeplInArgs) > 0) { DBusInputStream dbusInputStream(dbusMessage); - const bool success = DBusSerializableArguments<_InArgs...>::deserialize(dbusInputStream, std::get<_InArgIndices>(argTuple)...); + const bool success = DBusSerializableArguments<CommonAPI::Deployable<_InArgs, _DeplInArgs>...>::deserialize(dbusInputStream, std::get<_InArgIndices>(in_)...); if (!success) return false; } @@ -396,9 +428,11 @@ private: (stub.get()->*stubFunctor_)( clientId, - std::move(std::get<_InArgIndices>(argTuple))..., + std::move(std::get<_InArgIndices>(in_).getValue())..., [call, this](_OutArgs... _args){ - this->sendReply(call, std::make_tuple(_args...)); + this->sendReply(call, std::make_tuple(CommonAPI::Deployable<_OutArgs, _DeplOutArgs>( + _args, std::get<_OutArgIndices>(out_) + )...)); } ); @@ -408,13 +442,13 @@ private: template<int... _OutArgIndices> bool sendReplyInternal(CommonAPI::CallId_t _call, index_sequence<_OutArgIndices...>, - std::tuple<_OutArgs...> args) { + std::tuple<CommonAPI::Deployable<_OutArgs, _DeplOutArgs>...> args) { std::lock_guard<std::mutex> lock(mutex_); auto reply = pending_.find(_call); if (reply != pending_.end()) { - if (sizeof...(_OutArgs) > 0) { + if (sizeof...(_DeplOutArgs) > 0) { DBusOutputStream output(reply->second); - if (!DBusSerializableArguments<_OutArgs...>::serialize( + if (!DBusSerializableArguments<CommonAPI::Deployable<_OutArgs, _DeplOutArgs>...>::serialize( output, std::get<_OutArgIndices>(args)...)) { pending_.erase(_call); return false; @@ -430,8 +464,9 @@ private: _StubFunctor stubFunctor_; const char* dbusReplySignature_; - std::tuple<_InArgs..., _OutArgs...> args_; + std::tuple<CommonAPI::Deployable<_InArgs, _DeplInArgs>...> in_; + std::tuple<_DeplOutArgs*...> out_; CommonAPI::CallId_t currentCall_; std::map<CommonAPI::CallId_t, DBusMessage> pending_; std::mutex mutex_; // protects pending_ @@ -683,3 +718,4 @@ protected: } // namespace CommonAPI #endif // COMMONAPI_DBUS_DBUSSTUBADAPTERHELPER_HPP_ + diff --git a/include/CommonAPI/DBus/DBusTypeOutputStream.hpp b/include/CommonAPI/DBus/DBusTypeOutputStream.hpp index 928eadc..074d76a 100644 --- a/include/CommonAPI/DBus/DBusTypeOutputStream.hpp +++ b/include/CommonAPI/DBus/DBusTypeOutputStream.hpp @@ -116,20 +116,22 @@ public: template<typename _Deployment, typename... _Types> TypeOutputStream &writeType(const Variant<_Types...> &_value, const _Deployment *_depl) { - if (_depl != nullptr && _depl->isFreeDesktop_) { - signature_.append("v"); - } else { - signature_.append("(yv)"); - } - TypeOutputStreamWriteVisitor<DBusTypeOutputStream> typeVisitor(*this); - ApplyVoidVisitor<TypeOutputStreamWriteVisitor<DBusTypeOutputStream>, - Variant<_Types...>, _Types...>::visit(typeVisitor, _value); + if (_depl != nullptr && _depl->isDBus_) { + signature_.append("v"); + } else { + signature_.append("(yv)"); + } + TypeOutputStreamWriteVisitor<DBusTypeOutputStream> typeVisitor(*this); + ApplyVoidVisitor<TypeOutputStreamWriteVisitor<DBusTypeOutputStream>, + Variant<_Types...>, _Types...>::visit(typeVisitor, _value); return (*this); } template<typename _ElementType> TypeOutputStream &writeType(const std::vector<_ElementType> &_value) { signature_.append("a"); + _ElementType dummyElement; + writeType(dummyElement); return (*this); } |