summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schanda <schanda@itestra.de>2013-06-06 11:26:02 +0200
committerJohannes Schanda <schanda@itestra.de>2013-06-06 11:26:02 +0200
commit4ada91c04f494ecbce0f910f0008a94262d845f2 (patch)
tree020cf01ef9c85fe09b74f8ebf183c11ec98ed02e
parentfd34f6f90819ed1e9ac3e8525b155d06ce947805 (diff)
downloadgenivi-common-api-dbus-runtime-4ada91c04f494ecbce0f910f0008a94262d845f2.tar.gz
Working client side for legacy dbus attributes as fixed types and unions
in franca
-rw-r--r--Makefile.am3
-rw-r--r--src/CommonAPI/DBus/DBusAttribute.h461
-rw-r--r--src/CommonAPI/DBus/DBusEvent.h45
-rw-r--r--src/CommonAPI/DBus/DBusLegacyVariant.h130
-rw-r--r--src/CommonAPI/DBus/DBusProxyBase.h23
-rw-r--r--src/CommonAPI/DBus/DBusProxyHelper.h157
-rw-r--r--src/test/DBusTestUtils.h5
7 files changed, 759 insertions, 65 deletions
diff --git a/Makefile.am b/Makefile.am
index df4a358..f0af9f9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -89,7 +89,8 @@ CommonAPI_DBus_include_HEADERS = \
src/CommonAPI/DBus/DBusServiceStatusEvent.h \
src/CommonAPI/DBus/DBusStubAdapter.h \
src/CommonAPI/DBus/DBusStubAdapterHelper.h \
- src/CommonAPI/DBus/DBusUtils.h
+ src/CommonAPI/DBus/DBusUtils.h \
+ src/CommonAPI/DBus/DBusLegacyVariant.h
pkgconfigdir = ${libdir}/pkgconfig
pkgconfig_DATA = CommonAPI-DBus.pc
diff --git a/src/CommonAPI/DBus/DBusAttribute.h b/src/CommonAPI/DBus/DBusAttribute.h
index 4844b87..89cc61a 100644
--- a/src/CommonAPI/DBus/DBusAttribute.h
+++ b/src/CommonAPI/DBus/DBusAttribute.h
@@ -9,6 +9,8 @@
#include "DBusProxyHelper.h"
#include "DBusEvent.h"
+#include <stdint.h>
+#include "DBusLegacyVariant.h"
#include <cassert>
@@ -32,7 +34,8 @@ class DBusReadonlyAttribute: public _AttributeType {
}
void getValue(CallStatus& callStatus, ValueType& value) const {
- DBusProxyHelper<DBusSerializableArguments<>,
+
+ DBusProxyHelper<DBusSerializableArguments<>,
DBusSerializableArguments<ValueType> >::callMethodWithReply(dbusProxy_, getMethodName_, "", callStatus, value);
}
@@ -46,6 +49,132 @@ class DBusReadonlyAttribute: public _AttributeType {
const char* getMethodName_;
};
+template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
+class DBusFreedesktopReadonlyAttribute: public _AttributeType {
+ public:
+ typedef typename _AttributeType::ValueType ValueType;
+ typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+
+ DBusFreedesktopReadonlyAttribute(_DBusProxyType& dbusProxy, const char* interfaceName, const char* propertyName):
+ dbusProxy_(dbusProxy),
+ interfaceName_(interfaceName),
+ propertyName_(propertyName)
+ {
+ assert(interfaceName);
+ assert(propertyName);
+ }
+
+ void getValue(CallStatus& callStatus, ValueType& value) const {
+ DBusLegacyVariantWrapper<Variant<ValueType> > variantVal;
+ DBusProxyHelper<DBusSerializableArguments<std::string, std::string>,
+ DBusSerializableArguments<DBusLegacyVariantWrapper<Variant<ValueType> > > >::callMethodWithReply(
+ dbusProxy_,
+ dbusProxy_.getDBusBusName().c_str(),
+ dbusProxy_.getDBusObjectPath().c_str(),
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ "ss",
+ std::string(interfaceName_),
+ std::string(propertyName_),
+ callStatus,
+ variantVal);
+ value = variantVal.contained_.template get<ValueType>();
+
+ }
+
+ std::future<CallStatus> getValueAsync(AttributeAsyncCallback attributeAsyncCallback) {
+ return DBusProxyHelper<DBusSerializableArguments<std::string, std::string>,
+ DBusSerializableArguments<DBusLegacyVariantWrapper<Variant<ValueType> > > >::callMethodAsync(
+ dbusProxy_,
+ dbusProxy_.getDBusBusName().c_str(),
+ dbusProxy_.getDBusObjectPath().c_str(),
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ "ss",
+ std::string(interfaceName_),
+ std::string(propertyName_),
+ std::bind(
+ &CommonAPI::DBus::DBusFreedesktopReadonlyAttribute<_AttributeType>::AsyncVariantStripper,
+ this,
+ std::placeholders::_1,
+ std::placeholders::_2,
+ std::move(attributeAsyncCallback)));
+ }
+
+ void AsyncVariantStripper(const CommonAPI::CallStatus& status,
+ const DBusLegacyVariantWrapper<Variant<ValueType> >& value,
+ AttributeAsyncCallback attributeAsyncCallback) {
+ attributeAsyncCallback(status, value.contained_.template get<ValueType>());
+ }
+
+ protected:
+ _DBusProxyType& dbusProxy_;
+ const char* interfaceName_;
+ const char* propertyName_;
+};
+
+template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
+class DBusFreedesktopUnionReadonlyAttribute: public _AttributeType {
+ public:
+ typedef typename _AttributeType::ValueType ValueType;
+ typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+
+ DBusFreedesktopUnionReadonlyAttribute(_DBusProxyType& dbusProxy, const char* interfaceName, const char* propertyName):
+ dbusProxy_(dbusProxy),
+ interfaceName_(interfaceName),
+ propertyName_(propertyName)
+ {
+ assert(interfaceName);
+ assert(propertyName);
+ }
+
+ void getValue(CallStatus& callStatus, ValueType& value) const {
+ DBusLegacyVariantWrapper<ValueType> variantVal(value);
+ DBusProxyHelper<DBusSerializableArguments<std::string, std::string>,
+ DBusSerializableArguments<DBusLegacyVariantWrapper<ValueType> > >::callMethodWithReply(
+ dbusProxy_,
+ dbusProxy_.getDBusBusName().c_str(),
+ dbusProxy_.getDBusObjectPath().c_str(),
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ "ss",
+ std::string(interfaceName_),
+ std::string(propertyName_),
+ callStatus,
+ variantVal);
+ value = variantVal.contained_;
+ }
+
+ std::future<CallStatus> getValueAsync(AttributeAsyncCallback attributeAsyncCallback) {
+ return DBusProxyHelper<DBusSerializableArguments<std::string, std::string>,
+ DBusSerializableArguments<DBusLegacyVariantWrapper<ValueType> > >::callMethodAsync(
+ dbusProxy_,
+ dbusProxy_.getDBusBusName().c_str(),
+ dbusProxy_.getDBusObjectPath().c_str(),
+ "org.freedesktop.DBus.Properties",
+ "Get",
+ "ss",
+ std::string(interfaceName_),
+ std::string(propertyName_),
+ std::bind(
+ &CommonAPI::DBus::DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::AsyncVariantStripper,
+ this,
+ std::placeholders::_1,
+ std::placeholders::_2,
+ std::move(attributeAsyncCallback)));
+ }
+
+ void AsyncVariantStripper(const CommonAPI::CallStatus& status,
+ const DBusLegacyVariantWrapper<ValueType>& value,
+ AttributeAsyncCallback attributeAsyncCallback) {
+ attributeAsyncCallback(status, value.contained_);
+ }
+
+ protected:
+ _DBusProxyType& dbusProxy_;
+ const char* interfaceName_;
+ const char* propertyName_;
+};
template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
class DBusAttribute: public DBusReadonlyAttribute<_AttributeType> {
@@ -61,16 +190,17 @@ class DBusAttribute: public DBusReadonlyAttribute<_AttributeType> {
assert(setMethodSignature);
}
- void setValue(const ValueType& requestValue, CallStatus& callStatus, ValueType& responseValue) {
- DBusProxyHelper<DBusSerializableArguments<ValueType>,
- DBusSerializableArguments<ValueType> >::callMethodWithReply(
- this->dbusProxy_,
- setMethodName_,
- setMethodSignature_,
- requestValue,
- callStatus,
- responseValue);
- }
+ void setValue(const ValueType& requestValue, CallStatus& callStatus, ValueType& responseValue) {
+ DBusProxyHelper<DBusSerializableArguments<ValueType>,
+ DBusSerializableArguments<ValueType> >::callMethodWithReply(
+ this->dbusProxy_,
+ setMethodName_,
+ setMethodSignature_,
+ requestValue,
+ callStatus,
+ responseValue);
+ }
+
std::future<CallStatus> setValueAsync(const ValueType& requestValue, AttributeAsyncCallback attributeAsyncCallback) {
return DBusProxyHelper<DBusSerializableArguments<ValueType>,
@@ -87,6 +217,131 @@ class DBusAttribute: public DBusReadonlyAttribute<_AttributeType> {
const char* setMethodSignature_;
};
+template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
+class DBusFreedesktopAttribute: public DBusFreedesktopReadonlyAttribute<_AttributeType, _DBusProxyType> {
+ public:
+ typedef typename _AttributeType::ValueType ValueType;
+ typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+
+ DBusFreedesktopAttribute(_DBusProxyType& dbusProxy,
+ const char* interfaceName,
+ const char* propertyName) :
+ DBusFreedesktopReadonlyAttribute<_AttributeType>(dbusProxy, interfaceName, propertyName)
+ {
+ assert(interfaceName);
+ assert(propertyName);
+ }
+
+
+ void setValue(const ValueType& requestValue, CallStatus& callStatus, ValueType& responseValue) {
+ DBusLegacyVariantWrapper<Variant<ValueType> > variantVal;
+ variantVal.contained_ = Variant<ValueType>(requestValue);
+ DBusProxyHelper<DBusSerializableArguments<std::string, std::string, DBusLegacyVariantWrapper<Variant<ValueType> > >,
+ DBusSerializableArguments<> >::callMethodWithReply(
+ DBusFreedesktopReadonlyAttribute<_AttributeType>::dbusProxy_,
+ DBusFreedesktopReadonlyAttribute<_AttributeType>::dbusProxy_.getDBusBusName().c_str(),
+ DBusFreedesktopReadonlyAttribute<_AttributeType>::dbusProxy_.getDBusObjectPath().c_str(),
+ "org.freedesktop.DBus.Properties",
+ "Set",
+ "ssv",
+ std::string(DBusFreedesktopReadonlyAttribute<_AttributeType>::interfaceName_),
+ std::string(DBusFreedesktopReadonlyAttribute<_AttributeType>::propertyName_),
+ variantVal,
+ callStatus);
+ responseValue = requestValue;
+ }
+
+ std::future<CallStatus> setValueAsync(const ValueType& requestValue, AttributeAsyncCallback attributeAsyncCallback) {
+ DBusLegacyVariantWrapper<Variant<ValueType> > variantVal;
+ variantVal.contained_ = Variant<ValueType>(requestValue);
+ return DBusProxyHelper<DBusSerializableArguments<std::string, std::string, DBusLegacyVariantWrapper<Variant<ValueType> > >,
+ DBusSerializableArguments<> >::callMethodAsync(
+ DBusFreedesktopReadonlyAttribute<_AttributeType>::dbusProxy_,
+ DBusFreedesktopReadonlyAttribute<_AttributeType>::dbusProxy_.getDBusBusName().c_str(),
+ DBusFreedesktopReadonlyAttribute<_AttributeType>::dbusProxy_.getDBusObjectPath().c_str(),
+ "org.freedesktop.DBus.Properties",
+ "Set",
+ "ssv",
+ std::string(DBusFreedesktopReadonlyAttribute<_AttributeType>::interfaceName_),
+ std::string(DBusFreedesktopReadonlyAttribute<_AttributeType>::propertyName_),
+ variantVal,
+ std::bind(
+ &CommonAPI::DBus::DBusFreedesktopAttribute<_AttributeType>::AsyncVariantStripper,
+ this,
+ std::placeholders::_1,
+ variantVal,
+ std::move(attributeAsyncCallback)));
+ }
+
+ void AsyncVariantStripper(const CommonAPI::CallStatus& status,
+ const DBusLegacyVariantWrapper<Variant<ValueType> >& value,
+ AttributeAsyncCallback attributeAsyncCallback) {
+ attributeAsyncCallback(status, value.contained_.template get<ValueType>());
+ }
+};
+
+template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
+class DBusFreedesktopUnionAttribute: public DBusFreedesktopUnionReadonlyAttribute<_AttributeType, _DBusProxyType> {
+ public:
+ typedef typename _AttributeType::ValueType ValueType;
+ typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+
+ DBusFreedesktopUnionAttribute(_DBusProxyType& dbusProxy,
+ const char* interfaceName,
+ const char* propertyName) :
+ DBusFreedesktopUnionReadonlyAttribute<_AttributeType>(dbusProxy, interfaceName, propertyName)
+ {
+ assert(interfaceName);
+ assert(propertyName);
+ }
+
+
+ void setValue(const ValueType& requestValue, CallStatus& callStatus, ValueType& responseValue) {
+ DBusLegacyVariantWrapper<ValueType> variantVal;
+ variantVal.contained_ = requestValue;
+ DBusProxyHelper<DBusSerializableArguments<std::string, std::string, DBusLegacyVariantWrapper<ValueType> >,
+ DBusSerializableArguments<> >::callMethodWithReply(
+ DBusFreedesktopUnionAttribute<_AttributeType>::dbusProxy_,
+ DBusFreedesktopUnionAttribute<_AttributeType>::dbusProxy_.getDBusBusName().c_str(),
+ DBusFreedesktopUnionAttribute<_AttributeType>::dbusProxy_.getDBusObjectPath().c_str(),
+ "org.freedesktop.DBus.Properties",
+ "Set",
+ "ssv",
+ std::string(DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::interfaceName_),
+ std::string(DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::propertyName_),
+ variantVal,
+ callStatus);
+ responseValue = requestValue;
+ }
+
+ std::future<CallStatus> setValueAsync(const ValueType& requestValue, AttributeAsyncCallback attributeAsyncCallback) {
+ DBusLegacyVariantWrapper<ValueType> variantVal;
+ variantVal.contained_ = requestValue;
+ return DBusProxyHelper<DBusSerializableArguments<std::string, std::string, DBusLegacyVariantWrapper<ValueType> >,
+ DBusSerializableArguments<> >::callMethodAsync(
+ DBusFreedesktopUnionAttribute<_AttributeType>::dbusProxy_,
+ DBusFreedesktopUnionAttribute<_AttributeType>::dbusProxy_.getDBusBusName().c_str(),
+ DBusFreedesktopUnionAttribute<_AttributeType>::dbusProxy_.getDBusObjectPath().c_str(),
+ "org.freedesktop.DBus.Properties",
+ "Set",
+ "ssv",
+ std::string(DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::interfaceName_),
+ std::string(DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::propertyName_),
+ variantVal,
+ std::bind(
+ &CommonAPI::DBus::DBusFreedesktopUnionAttribute<_AttributeType>::AsyncVariantStripper,
+ this,
+ std::placeholders::_1,
+ variantVal,
+ std::move(attributeAsyncCallback)));
+ }
+
+ void AsyncVariantStripper(const CommonAPI::CallStatus& status,
+ const DBusLegacyVariantWrapper<ValueType>& value,
+ AttributeAsyncCallback attributeAsyncCallback) {
+ attributeAsyncCallback(status, value.contained_);
+ }
+};
template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
class DBusObservableAttribute: public _AttributeType {
@@ -109,6 +364,190 @@ class DBusObservableAttribute: public _AttributeType {
DBusEvent<ChangedEvent> changedEvent_;
};
+template< class, class >
+class LegacyEvent;
+
+template <template <class...> class _Type, class _Types, typename _DBusProxy>
+class LegacyEvent<_Type<_Types>, _DBusProxy> : public _Type<_Types> {
+public:
+ typedef _Types ValueType;
+ typedef _Type<ValueType> CommonAPIEvent;
+ typedef typename CommonAPIEvent::CancellableListener CancellableListener;
+
+ LegacyEvent(_DBusProxy& dbusProxy, const char* interfaceName, const char* propName) :
+ interfaceName_(interfaceName),
+ propertyName_(propName),
+ subSet_(false),
+ internalEvent_(dbusProxy, "PropertiesChanged", "sa{sv}as", dbusProxy.getDBusObjectPath().c_str(), "org.freedesktop.DBus.Properties") {
+ }
+
+protected:
+ void onInternalEvent(const std::string& interface,
+ const std::unordered_map<std::string, DBusLegacyVariantWrapper<Variant<_Types> > >& props,
+ const std::vector<std::string>& invalid) {
+ if (std::string(interfaceName_) == interface) {
+ auto mapIter = props.find(std::string(propertyName_));
+ if (mapIter != props.end()) {
+ notifyListeners(mapIter->second.contained_.template get<ValueType>());
+ }
+ }
+ }
+
+ void onFirstListenerAdded(const CancellableListener& listener) {
+ sub = internalEvent_.subscribe(
+ std::bind(
+ &LegacyEvent<_Type<_Types>, _DBusProxy>::onInternalEvent,
+ this,
+ std::placeholders::_1,
+ std::placeholders::_2,
+ std::placeholders::_3));
+ subSet_ = true;
+ }
+
+ void onLastListenerRemoved(const CancellableListener& listener) {
+ if (subSet_) {
+ internalEvent_.unsubscribe(sub);
+ subSet_ = false;
+ }
+ }
+
+ typedef DBusLegacyVariantWrapper<Variant<_Types> > ContainedVariant;
+ typedef std::unordered_map<std::string, ContainedVariant> PropertyMap;
+ typedef std::vector<std::string> InvalidArray;
+ typedef Event<std::string, PropertyMap, InvalidArray> SignalEvent;
+
+ DBusEvent<SignalEvent> internalEvent_;
+
+ typename DBusEvent<SignalEvent>::Subscription sub;
+
+ const char* interfaceName_;
+ const char* propertyName_;
+
+ bool subSet_;
+
+};
+
+template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
+class DBusFreedesktopObservableAttribute: public _AttributeType {
+ public:
+ typedef typename _AttributeType::ValueType ValueType;
+ typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+ typedef typename _AttributeType::ChangedEvent ChangedEvent;
+
+ template <typename... _AttributeTypeArguments>
+ DBusFreedesktopObservableAttribute(_DBusProxyType& dbusProxy,
+ const char* interfaceName,
+ const char* propertyName,
+ _AttributeTypeArguments... arguments):
+ _AttributeType(dbusProxy, interfaceName, propertyName, arguments...),
+ propertyName_(propertyName),
+ interfaceName_(interfaceName),
+ externalChangedEvent_(dbusProxy, interfaceName, propertyName) {
+
+ }
+
+ ChangedEvent& getChangedEvent() {
+ return externalChangedEvent_;
+ }
+
+ protected:
+ LegacyEvent<ChangedEvent, _DBusProxyType> externalChangedEvent_;
+ const char * propertyName_;
+ const char * interfaceName_;
+};
+
+template< class, class >
+class LegacyUnionEvent;
+
+template <template <class...> class _Type, class _Types, typename _DBusProxy>
+class LegacyUnionEvent<_Type<_Types>, _DBusProxy> : public _Type<_Types> {
+public:
+ typedef _Types ValueType;
+ typedef _Type<ValueType> CommonAPIEvent;
+ typedef typename CommonAPIEvent::CancellableListener CancellableListener;
+
+ LegacyUnionEvent(_DBusProxy& dbusProxy, const char* interfaceName, const char* propName) :
+ interfaceName_(interfaceName),
+ propertyName_(propName),
+ subSet_(false),
+ internalEvent_(dbusProxy, "PropertiesChanged", "sa{sv}as", dbusProxy.getDBusObjectPath().c_str(), "org.freedesktop.DBus.Properties") {
+ }
+
+protected:
+ void onInternalEvent(const std::string& interface,
+ const std::unordered_map<std::string, DBusLegacyVariantWrapper<ValueType> >& props,
+ const std::vector<std::string>& invalid) {
+ if (std::string(interfaceName_) == interface) {
+ auto mapIter = props.find(std::string(propertyName_));
+ if (mapIter != props.end()) {
+ notifyListeners(mapIter->second.contained_);
+ }
+ }
+ }
+
+ void onFirstListenerAdded(const CancellableListener& listener) {
+ sub = internalEvent_.subscribe(
+ std::bind(
+ &LegacyUnionEvent<_Type<_Types>, _DBusProxy>::onInternalEvent,
+ this,
+ std::placeholders::_1,
+ std::placeholders::_2,
+ std::placeholders::_3));
+ subSet_ = true;
+ }
+
+ void onLastListenerRemoved(const CancellableListener& listener) {
+ if (subSet_) {
+ internalEvent_.unsubscribe(sub);
+ subSet_ = false;
+ }
+ }
+
+ typedef DBusLegacyVariantWrapper<ValueType> ContainedVariant;
+ typedef std::unordered_map<std::string, ContainedVariant> PropertyMap;
+ typedef std::vector<std::string> InvalidArray;
+ typedef Event<std::string, PropertyMap, InvalidArray> SignalEvent;
+
+ DBusEvent<SignalEvent> internalEvent_;
+
+ typename DBusEvent<SignalEvent>::Subscription sub;
+
+ const char* interfaceName_;
+ const char* propertyName_;
+
+ bool subSet_;
+
+};
+
+template <typename _AttributeType, typename _DBusProxyType = DBusProxy>
+class DBusFreedesktopUnionObservableAttribute: public _AttributeType {
+ public:
+ typedef typename _AttributeType::ValueType ValueType;
+ typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback;
+ typedef typename _AttributeType::ChangedEvent ChangedEvent;
+
+ template <typename... _AttributeTypeArguments>
+ DBusFreedesktopUnionObservableAttribute(_DBusProxyType& dbusProxy,
+ const char* interfaceName,
+ const char* propertyName,
+ _AttributeTypeArguments... arguments):
+ _AttributeType(dbusProxy, interfaceName, propertyName, arguments...),
+ propertyName_(propertyName),
+ interfaceName_(interfaceName),
+ externalChangedEvent_(dbusProxy, interfaceName, propertyName) {
+
+ }
+
+ ChangedEvent& getChangedEvent() {
+ return externalChangedEvent_;
+ }
+
+ protected:
+ LegacyUnionEvent<ChangedEvent, _DBusProxyType> externalChangedEvent_;
+ const char * propertyName_;
+ const char * interfaceName_;
+};
+
} // namespace DBus
} // namespace CommonAPI
diff --git a/src/CommonAPI/DBus/DBusEvent.h b/src/CommonAPI/DBus/DBusEvent.h
index 46ba4ab..561fa04 100644
--- a/src/CommonAPI/DBus/DBusEvent.h
+++ b/src/CommonAPI/DBus/DBusEvent.h
@@ -30,10 +30,26 @@ class DBusEvent: public _EventType, public DBusProxyConnection::DBusSignalHandle
dbusProxy_(dbusProxy),
eventName_(eventName),
eventSignature_(eventSignature) {
- assert(eventName);
- assert(eventSignature);
+ interfaceName_ = dbusProxy.getInterfaceName().c_str();
+ objectPath_ = dbusProxy_.getDBusObjectPath().c_str();
+ assert(eventName_);
+ assert(eventSignature_);
+ assert(objectPath_);
+ assert(interfaceName_);
}
+ DBusEvent(_DBusProxy& dbusProxy, const char* eventName, const char* eventSignature, const char* objPath, const char* interfaceName) :
+ dbusProxy_(dbusProxy),
+ eventName_(eventName),
+ eventSignature_(eventSignature),
+ objectPath_(objPath),
+ interfaceName_(interfaceName) {
+ assert(eventName);
+ assert(eventSignature);
+ assert(objPath);
+ assert(interfaceName);
+ }
+
virtual ~DBusEvent() {
if (this->hasListeners())
dbusProxy_.removeSignalMemberHandler(subscription_);
@@ -45,30 +61,36 @@ class DBusEvent: public _EventType, public DBusProxyConnection::DBusSignalHandle
protected:
virtual void onFirstListenerAdded(const CancellableListener&) {
- subscription_ = dbusProxy_.addSignalMemberHandler(eventName_, eventSignature_, this);
+ subscription_ = dbusProxy_.addSignalMemberHandler(objectPath_, interfaceName_,
+ eventName_, eventSignature_, this);
}
virtual void onLastListenerRemoved(const CancellableListener&) {
dbusProxy_.removeSignalMemberHandler(subscription_);
}
- private:
template <typename ... _Arguments>
inline SubscriptionStatus unpackArgumentsAndHandleSignalDBusMessage(const DBusMessage& dbusMessage, std::tuple<_Arguments...> argTuple) {
return handleSignalDBusMessage(dbusMessage, std::move(argTuple), typename make_sequence<sizeof...(_Arguments)>::type());
}
- template <typename ... _Arguments, int... _ArgIndices>
- inline SubscriptionStatus handleSignalDBusMessage(const DBusMessage& dbusMessage, std::tuple<_Arguments...> argTuple, index_sequence<_ArgIndices...>) {
- DBusInputStream dbusInputStream(dbusMessage);
- const bool success = DBusSerializableArguments<_Arguments...>::deserialize(dbusInputStream, std::get<_ArgIndices>(argTuple)...);
- // Continue subscription if deserialization failed
- return success ? this->notifyListeners(std::get<_ArgIndices>(argTuple)...) : SubscriptionStatus::RETAIN;
- }
+ template<typename ... _Arguments, int ... _ArgIndices>
+ inline SubscriptionStatus handleSignalDBusMessage(const DBusMessage& dbusMessage,
+ std::tuple<_Arguments...> argTuple,
+ index_sequence<_ArgIndices...>) {
+ DBusInputStream dbusInputStream(dbusMessage);
+ const bool success = DBusSerializableArguments<_Arguments...>::deserialize(
+ dbusInputStream,
+ std::get<_ArgIndices>(argTuple)...);
+ // Continue subscription if deserialization failed
+ return success ? this->notifyListeners(std::get<_ArgIndices>(argTuple)...) : SubscriptionStatus::RETAIN;
+ }
_DBusProxy& dbusProxy_;
const char* eventName_;
const char* eventSignature_;
+ const char* interfaceName_;
+ const char* objectPath_;
DBusProxyConnection::DBusSignalHandlerToken subscription_;
};
@@ -76,3 +98,4 @@ class DBusEvent: public _EventType, public DBusProxyConnection::DBusSignalHandle
} // namespace CommonAPI
#endif // COMMONAPI_DBUS_DBUS_EVENT_H_
+
diff --git a/src/CommonAPI/DBus/DBusLegacyVariant.h b/src/CommonAPI/DBus/DBusLegacyVariant.h
new file mode 100644
index 0000000..1403dea
--- /dev/null
+++ b/src/CommonAPI/DBus/DBusLegacyVariant.h
@@ -0,0 +1,130 @@
+/* Copyright (C) 2013 BMW Group
+ * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
+ * Author: Juergen Gehring (juergen.gehring@bmw.de)
+ * 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 DBUSLEGACYVARIANT_H_
+#define DBUSLEGACYVARIANT_H_
+
+#include <CommonAPI/SerializableVariant.h>
+#include "DBusOutputStream.h"
+#include "DBusInputStream.h"
+
+namespace CommonAPI {
+namespace DBus {
+
+template<class Visitor, class Variant, typename ... _Types>
+struct ApplyIndexForStringVisitor
+;
+
+template<class Visitor, class Variant>
+struct ApplyIndexForStringVisitor<Visitor, Variant> {
+ static const uint8_t index = 0;
+
+ static uint8_t visit(Visitor&, const Variant&) {
+ //won't be called
+ assert(false);
+ return 0;
+ }
+};
+
+template<class Visitor, class Variant, typename _Type, typename ... _Types>
+struct ApplyIndexForStringVisitor<Visitor, Variant, _Type, _Types...> {
+ static const uint8_t index = ApplyIndexForStringVisitor<Visitor, Variant,
+ _Types...>::index + 1;
+
+ static uint8_t visit(Visitor& visitor, const Variant& var) {
+ DBusTypeOutputStream typeStream_;
+ TypeWriter<_Type>::writeType(typeStream_);
+ const std::string sig = typeStream_.retrieveSignature();
+ if (visitor.template operator()<_Type>(sig)) {
+ return index;
+ } else {
+ return ApplyIndexForStringVisitor<Visitor, Variant, _Types...>::visit(visitor,
+ var);
+ }
+ }
+};
+
+template<typename ... _Types>
+struct TypeOutputStreamCompareVisitor {
+public:
+ TypeOutputStreamCompareVisitor(const std::string& type) :
+ type_(type) {
+ }
+
+ template<typename _Type>
+ bool operator()(const std::string& ntype) const {
+ int comp = type_.compare(0, type_.size(), ntype);
+ if (comp == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+private:
+ const std::string type_;
+
+};
+
+template< class >
+class DBusLegacyVariantWrapper;
+
+template <
+ template <class...> class _Type, class... _Types>
+class DBusLegacyVariantWrapper<_Type<_Types...>> {
+public:
+
+ DBusLegacyVariantWrapper() :
+ contained_() {
+ }
+
+ DBusLegacyVariantWrapper(CommonAPI::Variant<_Types...>& cont) :
+ contained_(cont) {
+ }
+
+
+ uint8_t getIndexForType(const std::string& type) const {
+ TypeOutputStreamCompareVisitor<_Types...> visitor(type);
+ return ApplyIndexForStringVisitor<TypeOutputStreamCompareVisitor<_Types...>, Variant<_Types...>, _Types...>::visit(
+ visitor, contained_);
+ }
+
+ CommonAPI::Variant<_Types...> contained_;
+};
+
+} /* namespace DBus */
+
+//template <template <class...> class _Type, class... _Types>
+template <typename ... _Types>
+inline OutputStream& operator<<(OutputStream& outputStream, const DBus::DBusLegacyVariantWrapper<Variant<_Types...> >& serializableVariant) {
+ DBus::DBusTypeOutputStream typeOutputStream;
+ serializableVariant.contained_.writeToTypeOutputStream(typeOutputStream);
+ std::string sigStr = typeOutputStream.retrieveSignature();
+ uint8_t length = (uint8_t) sigStr.length();
+ assert(length < 256);
+ outputStream << length;
+ outputStream.writeRawData(sigStr.c_str(), length + 1);
+ serializableVariant.contained_.writeToOutputStream(outputStream);
+ return outputStream;
+}
+
+//template <template <class...> class _Type, class... _Types>
+template <typename ... _Types>
+inline InputStream& operator>>(InputStream& inputStream, DBus::DBusLegacyVariantWrapper<Variant<_Types...> >& serializableVariant) {
+ uint8_t signatureLength;
+ inputStream.readValue(signatureLength);
+ assert(signatureLength < 256);
+ char * buf = inputStream.readRawData(signatureLength + 1);
+ std::string sigString;
+ sigString.assign(buf, buf + signatureLength);
+ uint8_t containedTypeIndex = serializableVariant.getIndexForType(sigString);
+ serializableVariant.contained_.readFromInputStream(containedTypeIndex, inputStream);
+ return inputStream;
+}
+
+} /* namespace CommonAPI */
+
+#endif /* DBUSLEGACYVARIANT_H_ */
diff --git a/src/CommonAPI/DBus/DBusProxyBase.h b/src/CommonAPI/DBus/DBusProxyBase.h
index 686c878..454d03f 100644
--- a/src/CommonAPI/DBus/DBusProxyBase.h
+++ b/src/CommonAPI/DBus/DBusProxyBase.h
@@ -41,6 +41,13 @@ class DBusProxyBase: public virtual CommonAPI::Proxy {
const std::string& signalSignature,
DBusProxyConnection::DBusSignalHandler* dbusSignalHandler);
+ inline DBusProxyConnection::DBusSignalHandlerToken addSignalMemberHandler(
+ const std::string& objectPath,
+ const std::string& interfaceName,
+ const std::string& signalName,
+ const std::string& signalSignature,
+ DBusProxyConnection::DBusSignalHandler* dbusSignalHandler);
+
inline void removeSignalMemberHandler(const DBusProxyConnection::DBusSignalHandlerToken& dbusSignalHandlerToken);
protected:
@@ -60,7 +67,7 @@ DBusProxyConnection::DBusSignalHandlerToken DBusProxyBase::addSignalMemberHandle
const std::string& signalName,
const std::string& signalSignature,
DBusProxyConnection::DBusSignalHandler* dbusSignalHandler) {
- return dbusConnection_->addSignalMemberHandler(
+ return addSignalMemberHandler(
getDBusObjectPath(),
getInterfaceName(),
signalName,
@@ -68,6 +75,20 @@ DBusProxyConnection::DBusSignalHandlerToken DBusProxyBase::addSignalMemberHandle
dbusSignalHandler);
}
+DBusProxyConnection::DBusSignalHandlerToken DBusProxyBase::addSignalMemberHandler(
+ const std::string& objectPath,
+ const std::string& interfaceName,
+ const std::string& signalName,
+ const std::string& signalSignature,
+ DBusProxyConnection::DBusSignalHandler* dbusSignalHandler) {
+ return dbusConnection_->addSignalMemberHandler(
+ objectPath,
+ interfaceName,
+ signalName,
+ signalSignature,
+ dbusSignalHandler);
+}
+
void DBusProxyBase::removeSignalMemberHandler(const DBusProxyConnection::DBusSignalHandlerToken& dbusSignalHandlerToken) {
return dbusConnection_->removeSignalMemberHandler(dbusSignalHandlerToken);
}
diff --git a/src/CommonAPI/DBus/DBusProxyHelper.h b/src/CommonAPI/DBus/DBusProxyHelper.h
index 5483d2b..48433d7 100644
--- a/src/CommonAPI/DBus/DBusProxyHelper.h
+++ b/src/CommonAPI/DBus/DBusProxyHelper.h
@@ -59,6 +59,66 @@ struct DBusProxyHelper<_In<_InArgs...>, _Out<_OutArgs...>> {
}
template <typename _DBusProxy = DBusProxy>
+ static void callMethodWithReply(
+ const _DBusProxy& dbusProxy,
+ DBusMessage& dbusMethodCall,
+ const _InArgs&... inArgs,
+ CommonAPI::CallStatus& callStatus,
+ _OutArgs&... outArgs) {
+
+ if (sizeof...(_InArgs) > 0) {
+ DBusOutputStream outputStream(dbusMethodCall);
+ const bool success = DBusSerializableArguments<_InArgs...>::serialize(outputStream, inArgs...);
+ if (!success) {
+ callStatus = CallStatus::OUT_OF_MEMORY;
+ return;
+ }
+ outputStream.flush();
+ }
+
+ DBusError dbusError;
+ DBusMessage dbusMessageReply = dbusProxy.getDBusConnection()->sendDBusMessageWithReplyAndBlock(dbusMethodCall, dbusError);
+ if (dbusError || !dbusMessageReply.isMethodReturnType()) {
+ callStatus = CallStatus::REMOTE_ERROR;
+ return;
+ }
+
+ if (sizeof...(_OutArgs) > 0) {
+ DBusInputStream inputStream(dbusMessageReply);
+ const bool success = DBusSerializableArguments<_OutArgs...>::deserialize(inputStream, outArgs...);
+ if (!success) {
+ callStatus = CallStatus::REMOTE_ERROR;
+ return;
+ }
+ }
+ callStatus = CallStatus::SUCCESS;
+ }
+
+ template <typename _DBusProxy = DBusProxy>
+ static void callMethodWithReply(
+ const _DBusProxy& dbusProxy,
+ const char* busName,
+ const char* objPath,
+ const char* interfaceName,
+ const char* methodName,
+ const char* methodSignature,
+ const _InArgs&... inArgs,
+ CommonAPI::CallStatus& callStatus,
+ _OutArgs&... outArgs) {
+ if (dbusProxy.isAvailableBlocking()) {
+ DBusMessage dbusMethodCall = DBusMessage::createMethodCall(
+ busName,
+ objPath,
+ interfaceName,
+ methodName,
+ methodSignature);
+ callMethodWithReply(dbusProxy, dbusMethodCall, inArgs..., callStatus, outArgs...);
+ } else {
+ callStatus = CallStatus::NOT_AVAILABLE;
+ }
+ }
+
+ template <typename _DBusProxy = DBusProxy>
static void callMethodWithReply(
const _DBusProxy& dbusProxy,
const char* methodName,
@@ -71,50 +131,76 @@ struct DBusProxyHelper<_In<_InArgs...>, _Out<_OutArgs...>> {
DBusMessage dbusMethodCall = dbusProxy.createMethodCall(methodName, methodSignature);
- if (sizeof...(_InArgs) > 0) {
- DBusOutputStream outputStream(dbusMethodCall);
- const bool success = DBusSerializableArguments<_InArgs...>::serialize(outputStream, inArgs...);
- if (!success) {
- callStatus = CallStatus::OUT_OF_MEMORY;
- return;
- }
- outputStream.flush();
- }
+ callMethodWithReply(dbusProxy, dbusMethodCall, inArgs..., callStatus, outArgs...);
- DBusError dbusError;
- DBusMessage dbusMessageReply = dbusProxy.getDBusConnection()->sendDBusMessageWithReplyAndBlock(dbusMethodCall, dbusError);
- if (dbusError || !dbusMessageReply.isMethodReturnType()) {
- callStatus = CallStatus::REMOTE_ERROR;
- return;
- }
+ } else {
+ callStatus = CallStatus::NOT_AVAILABLE;
+ }
+ }
- if (sizeof...(_OutArgs) > 0) {
- DBusInputStream inputStream(dbusMessageReply);
- const bool success = DBusSerializableArguments<_OutArgs...>::deserialize(inputStream, outArgs...);
- if (!success) {
- callStatus = CallStatus::REMOTE_ERROR;
- return;
- }
- }
+ template <typename _DBusProxy = DBusProxy, typename _AsyncCallback>
+ static std::future<CallStatus> callMethodAsync(
+ const _DBusProxy& dbusProxy,
+ const char* methodName,
+ const char* methodSignature,
+ const _InArgs&... inArgs,
+ _AsyncCallback asyncCallback) {
+ if (dbusProxy.isAvailable()) {
+ DBusMessage dbusMethodCall = dbusProxy.createMethodCall(methodName, methodSignature);
+
+ return callMethodAsync(dbusProxy, dbusMethodCall, inArgs..., asyncCallback);
- callStatus = CallStatus::SUCCESS;
} else {
- callStatus = CallStatus::NOT_AVAILABLE;
+
+ CallStatus callStatus = CallStatus::NOT_AVAILABLE;
+
+ callCallbackOnNotAvailable(asyncCallback, typename make_sequence<sizeof...(_OutArgs)>::type());
+
+ std::promise<CallStatus> promise;
+ promise.set_value(callStatus);
+ return promise.get_future();
}
+
}
+ template <typename _DBusProxy = DBusProxy, typename _AsyncCallback>
+ static std::future<CallStatus> callMethodAsync(
+ const _DBusProxy& dbusProxy,
+ const char* busName,
+ const char* objPath,
+ const char* interfaceName,
+ const char* methodName,
+ const char* methodSignature,
+ const _InArgs&... inArgs,
+ _AsyncCallback asyncCallback) {
+ if (dbusProxy.isAvailable()) {
+ DBusMessage dbusMethodCall = DBusMessage::createMethodCall(
+ busName,
+ objPath,
+ interfaceName,
+ methodName,
+ methodSignature);
+ return callMethodAsync(dbusProxy, dbusMethodCall, inArgs..., asyncCallback);
+ } else {
+
+ CallStatus callStatus = CallStatus::NOT_AVAILABLE;
+
+ callCallbackOnNotAvailable(asyncCallback, typename make_sequence<sizeof...(_OutArgs)>::type());
+
+ std::promise<CallStatus> promise;
+ promise.set_value(callStatus);
+ return promise.get_future();
+ }
+ }
+
+
template <typename _DBusProxy = DBusProxy, typename _AsyncCallback>
static std::future<CallStatus> callMethodAsync(
const _DBusProxy& dbusProxy,
- const char* methodName,
- const char* methodSignature,
+ DBusMessage& dbusMessage,
const _InArgs&... inArgs,
_AsyncCallback asyncCallback) {
- if (dbusProxy.isAvailable()) {
-
- DBusMessage dbusMessage = dbusProxy.createMethodCall(methodName, methodSignature);
-
if (sizeof...(_InArgs) > 0) {
DBusOutputStream outputStream(dbusMessage);
const bool success = DBusSerializableArguments<_InArgs...>::serialize(outputStream, inArgs...);
@@ -129,16 +215,7 @@ struct DBusProxyHelper<_In<_InArgs...>, _Out<_OutArgs...>> {
return dbusProxy.getDBusConnection()->sendDBusMessageWithReplyAsync(
dbusMessage,
DBusProxyAsyncCallbackHandler<_OutArgs...>::create(std::move(asyncCallback)));
- } else {
-
- CallStatus callStatus = CallStatus::NOT_AVAILABLE;
- callCallbackOnNotAvailable(asyncCallback, typename make_sequence<sizeof...(_OutArgs)>::type());
-
- std::promise<CallStatus> promise;
- promise.set_value(callStatus);
- return promise.get_future();
- }
}
template <int... _ArgIndices>
diff --git a/src/test/DBusTestUtils.h b/src/test/DBusTestUtils.h
index a1140e4..476840b 100644
--- a/src/test/DBusTestUtils.h
+++ b/src/test/DBusTestUtils.h
@@ -5,10 +5,12 @@
* 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 __DBUS_TEST_UTILS__
+#define __DBUS_TEST_UTILS__
+
#include <dbus/dbus.h>
#include <CommonAPI/DBus/DBusServiceRegistry.h>
-
inline char eliminateZeroes(char val) {
return !val ? '0' : val;
}
@@ -73,3 +75,4 @@ inline std::string toString(CommonAPI::CallStatus state) {
return "SUCCESS";
}
}
+#endif //__DBUS_TEST_UTILS__