summaryrefslogtreecommitdiff
path: root/include/CommonAPI
diff options
context:
space:
mode:
Diffstat (limited to 'include/CommonAPI')
-rw-r--r--include/CommonAPI/DBus/CommonAPIDBus.hpp18
-rw-r--r--include/CommonAPI/DBus/DBusAddressTranslator.hpp19
-rw-r--r--include/CommonAPI/DBus/DBusAttribute.hpp2
-rw-r--r--include/CommonAPI/DBus/DBusConnection.hpp15
-rw-r--r--include/CommonAPI/DBus/DBusDeployment.hpp26
-rw-r--r--include/CommonAPI/DBus/DBusEvent.hpp50
-rw-r--r--include/CommonAPI/DBus/DBusFreedesktopAttribute.hpp31
-rw-r--r--include/CommonAPI/DBus/DBusFreedesktopStubAdapterHelper.hpp67
-rw-r--r--include/CommonAPI/DBus/DBusInputStream.hpp38
-rw-r--r--include/CommonAPI/DBus/DBusInstanceAvailabilityStatusChangedEvent.hpp20
-rw-r--r--include/CommonAPI/DBus/DBusMainLoopContext.hpp8
-rw-r--r--include/CommonAPI/DBus/DBusOutputStream.hpp46
-rw-r--r--include/CommonAPI/DBus/DBusProxy.hpp53
-rw-r--r--include/CommonAPI/DBus/DBusProxyAsyncSignalMemberCallbackHandler.hpp68
-rw-r--r--include/CommonAPI/DBus/DBusProxyBase.hpp30
-rw-r--r--include/CommonAPI/DBus/DBusProxyConnection.hpp3
-rw-r--r--include/CommonAPI/DBus/DBusProxyHelper.hpp8
-rw-r--r--include/CommonAPI/DBus/DBusStubAdapterHelper.hpp96
-rw-r--r--include/CommonAPI/DBus/DBusTypeOutputStream.hpp18
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);
}