diff options
Diffstat (limited to 'src/CommonAPI')
-rw-r--r-- | src/CommonAPI/DBus/DBusAttribute.h | 172 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusEvent.h | 2 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp | 110 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.h | 60 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusFunctionalHash.cpp | 96 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusFunctionalHash.h | 25 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusInterfaceHandler.h | 2 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusLegacyVariant.h | 4 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusObjectManager.cpp | 17 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusObjectManager.h | 2 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusObjectManagerStub.cpp | 8 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusObjectManagerStub.h | 1 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusOutputStream.h | 4 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusStubAdapter.cpp | 4 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusStubAdapter.h | 3 | ||||
-rw-r--r-- | src/CommonAPI/DBus/DBusStubAdapterHelper.h | 388 |
16 files changed, 724 insertions, 174 deletions
diff --git a/src/CommonAPI/DBus/DBusAttribute.h b/src/CommonAPI/DBus/DBusAttribute.h index adac105..146a190 100644 --- a/src/CommonAPI/DBus/DBusAttribute.h +++ b/src/CommonAPI/DBus/DBusAttribute.h @@ -29,31 +29,31 @@ class DBusProxy; template <typename _AttributeType, typename _DBusProxyType = DBusProxy> class DBusReadonlyAttribute: public _AttributeType { public: - typedef typename _AttributeType::ValueType ValueType; - typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback; + typedef typename _AttributeType::ValueType ValueType; + typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback; - DBusReadonlyAttribute(_DBusProxyType& dbusProxy, const char* setMethodSignature, const char* getMethodName): - dbusProxy_(dbusProxy), - getMethodName_(getMethodName), - setMethodSignature_(setMethodSignature) { - assert(getMethodName); - } + DBusReadonlyAttribute(_DBusProxyType& dbusProxy, const char* setMethodSignature, const char* getMethodName): + dbusProxy_(dbusProxy), + getMethodName_(getMethodName), + setMethodSignature_(setMethodSignature) { + assert(getMethodName); + } - void getValue(CallStatus& callStatus, ValueType& value) const { + void getValue(CallStatus& callStatus, ValueType& value) const { - DBusProxyHelper<DBusSerializableArguments<>, - DBusSerializableArguments<ValueType> >::callMethodWithReply(dbusProxy_, getMethodName_, "", callStatus, value); - } + DBusProxyHelper<DBusSerializableArguments<>, + DBusSerializableArguments<ValueType> >::callMethodWithReply(dbusProxy_, getMethodName_, "", callStatus, value); + } - std::future<CallStatus> getValueAsync(AttributeAsyncCallback attributeAsyncCallback) { - return DBusProxyHelper<DBusSerializableArguments<>, - DBusSerializableArguments<ValueType> >::callMethodAsync(dbusProxy_, getMethodName_, "", std::move(attributeAsyncCallback)); - } + std::future<CallStatus> getValueAsync(AttributeAsyncCallback attributeAsyncCallback) { + return DBusProxyHelper<DBusSerializableArguments<>, + DBusSerializableArguments<ValueType> >::callMethodAsync(dbusProxy_, getMethodName_, "", std::move(attributeAsyncCallback)); + } protected: - _DBusProxyType& dbusProxy_; - const char* getMethodName_; - const char* setMethodSignature_; + _DBusProxyType& dbusProxy_; + const char* getMethodName_; + const char* setMethodSignature_; }; template <typename _AttributeType, typename _DBusProxyType = DBusProxy> @@ -81,8 +81,8 @@ class DBusFreedesktopReadonlyAttribute: public _AttributeType { "org.freedesktop.DBus.Properties", "Get", "ss", - std::string(interfaceName_), - std::string(propertyName_), + interfaceName_, + propertyName_, callStatus, variantVal); value = variantVal.contained_.template get<ValueType>(); @@ -98,8 +98,8 @@ class DBusFreedesktopReadonlyAttribute: public _AttributeType { "org.freedesktop.DBus.Properties", "Get", "ss", - std::string(interfaceName_), - std::string(propertyName_), + interfaceName_, + propertyName_, std::bind( &CommonAPI::DBus::DBusFreedesktopReadonlyAttribute<_AttributeType>::AsyncVariantStripper, this, @@ -116,8 +116,8 @@ class DBusFreedesktopReadonlyAttribute: public _AttributeType { protected: _DBusProxyType& dbusProxy_; - const char* interfaceName_; - const char* propertyName_; + const std::string interfaceName_; + const std::string propertyName_; }; template <typename _AttributeType, typename _DBusProxyType = DBusProxy> @@ -145,8 +145,8 @@ class DBusFreedesktopUnionReadonlyAttribute: public _AttributeType { "org.freedesktop.DBus.Properties", "Get", "ss", - std::string(interfaceName_), - std::string(propertyName_), + interfaceName_, + propertyName_, callStatus, variantVal); value = variantVal.contained_; @@ -161,8 +161,8 @@ class DBusFreedesktopUnionReadonlyAttribute: public _AttributeType { "org.freedesktop.DBus.Properties", "Get", "ss", - std::string(interfaceName_), - std::string(propertyName_), + interfaceName_, + propertyName_, std::bind( &CommonAPI::DBus::DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::AsyncVariantStripper, this, @@ -179,23 +179,23 @@ class DBusFreedesktopUnionReadonlyAttribute: public _AttributeType { protected: _DBusProxyType& dbusProxy_; - const char* interfaceName_; - const char* propertyName_; + const std::string interfaceName_; + const std::string propertyName_; }; template <typename _AttributeType, typename _DBusProxyType = DBusProxy> class DBusAttribute: public DBusReadonlyAttribute<_AttributeType> { public: - typedef typename _AttributeType::ValueType ValueType; - typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback; + typedef typename _AttributeType::ValueType ValueType; + typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback; - DBusAttribute(_DBusProxyType& dbusProxy, const char* setMethodName, const char* setMethodSignature, const char* getMethodName): - DBusReadonlyAttribute<_AttributeType>(dbusProxy, setMethodSignature, getMethodName), - setMethodName_(setMethodName), - setMethodSignature_(setMethodSignature) { - assert(setMethodName); - assert(setMethodSignature); - } + DBusAttribute(_DBusProxyType& dbusProxy, const char* setMethodName, const char* setMethodSignature, const char* getMethodName): + DBusReadonlyAttribute<_AttributeType>(dbusProxy, setMethodSignature, getMethodName), + setMethodName_(setMethodName), + setMethodSignature_(setMethodSignature) { + assert(setMethodName); + assert(setMethodSignature); + } void setValue(const ValueType& requestValue, CallStatus& callStatus, ValueType& responseValue) { DBusProxyHelper<DBusSerializableArguments<ValueType>, @@ -209,19 +209,19 @@ class DBusAttribute: public DBusReadonlyAttribute<_AttributeType> { } - std::future<CallStatus> setValueAsync(const ValueType& requestValue, AttributeAsyncCallback attributeAsyncCallback) { - return DBusProxyHelper<DBusSerializableArguments<ValueType>, - DBusSerializableArguments<ValueType> >::callMethodAsync( - this->dbusProxy_, - setMethodName_, - setMethodSignature_, - requestValue, - attributeAsyncCallback); - } + std::future<CallStatus> setValueAsync(const ValueType& requestValue, AttributeAsyncCallback attributeAsyncCallback) { + return DBusProxyHelper<DBusSerializableArguments<ValueType>, + DBusSerializableArguments<ValueType> >::callMethodAsync( + this->dbusProxy_, + setMethodName_, + setMethodSignature_, + requestValue, + attributeAsyncCallback); + } protected: - const char* setMethodName_; - const char* setMethodSignature_; + const char* setMethodName_; + const char* setMethodSignature_; }; template <typename _AttributeType, typename _DBusProxyType = DBusProxy> @@ -251,8 +251,8 @@ class DBusFreedesktopAttribute: public DBusFreedesktopReadonlyAttribute<_Attribu "org.freedesktop.DBus.Properties", "Set", "ssv", - std::string(DBusFreedesktopReadonlyAttribute<_AttributeType>::interfaceName_), - std::string(DBusFreedesktopReadonlyAttribute<_AttributeType>::propertyName_), + DBusFreedesktopReadonlyAttribute<_AttributeType>::interfaceName_, + DBusFreedesktopReadonlyAttribute<_AttributeType>::propertyName_, variantVal, callStatus); responseValue = requestValue; @@ -269,8 +269,8 @@ class DBusFreedesktopAttribute: public DBusFreedesktopReadonlyAttribute<_Attribu "org.freedesktop.DBus.Properties", "Set", "ssv", - std::string(DBusFreedesktopReadonlyAttribute<_AttributeType>::interfaceName_), - std::string(DBusFreedesktopReadonlyAttribute<_AttributeType>::propertyName_), + DBusFreedesktopReadonlyAttribute<_AttributeType>::interfaceName_, + DBusFreedesktopReadonlyAttribute<_AttributeType>::propertyName_, variantVal, std::bind( &CommonAPI::DBus::DBusFreedesktopAttribute<_AttributeType>::AsyncVariantStripper, @@ -314,8 +314,8 @@ class DBusFreedesktopUnionAttribute: public DBusFreedesktopUnionReadonlyAttribut "org.freedesktop.DBus.Properties", "Set", "ssv", - std::string(DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::interfaceName_), - std::string(DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::propertyName_), + DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::interfaceName_, + DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::propertyName_, variantVal, callStatus); responseValue = requestValue; @@ -332,8 +332,8 @@ class DBusFreedesktopUnionAttribute: public DBusFreedesktopUnionReadonlyAttribut "org.freedesktop.DBus.Properties", "Set", "ssv", - std::string(DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::interfaceName_), - std::string(DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::propertyName_), + DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::interfaceName_, + DBusFreedesktopUnionReadonlyAttribute<_AttributeType>::propertyName_, variantVal, std::bind( &CommonAPI::DBus::DBusFreedesktopUnionAttribute<_AttributeType>::AsyncVariantStripper, @@ -353,22 +353,22 @@ class DBusFreedesktopUnionAttribute: public DBusFreedesktopUnionReadonlyAttribut template <typename _AttributeType, typename _DBusProxyType = DBusProxy> class DBusObservableAttribute: public _AttributeType { public: - typedef typename _AttributeType::ValueType ValueType; - typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback; - typedef typename _AttributeType::ChangedEvent ChangedEvent; + typedef typename _AttributeType::ValueType ValueType; + typedef typename _AttributeType::AttributeAsyncCallback AttributeAsyncCallback; + typedef typename _AttributeType::ChangedEvent ChangedEvent; - template <typename... _AttributeTypeArguments> - DBusObservableAttribute(_DBusProxyType& dbusProxy, const char* changedEventName, _AttributeTypeArguments... arguments): - _AttributeType(dbusProxy, arguments...), - changedEvent_(dbusProxy, changedEventName, this->setMethodSignature_) { - } + template <typename... _AttributeTypeArguments> + DBusObservableAttribute(_DBusProxyType& dbusProxy, const char* changedEventName, _AttributeTypeArguments... arguments): + _AttributeType(dbusProxy, arguments...), + changedEvent_(dbusProxy, changedEventName, this->setMethodSignature_) { + } - ChangedEvent& getChangedEvent() { - return changedEvent_; - } + ChangedEvent& getChangedEvent() { + return changedEvent_; + } protected: - DBusEvent<ChangedEvent> changedEvent_; + DBusEvent<ChangedEvent> changedEvent_; }; template< class, class > @@ -392,8 +392,8 @@ protected: void onInternalEvent(const std::string& interfaceName, const std::unordered_map<std::string, DBusLegacyVariantWrapper<Variant<_Types> > >& props, const std::vector<std::string>& invalid) { - if (std::string(interfaceName_) == interfaceName) { - auto mapIter = props.find(std::string(propertyName_)); + if (interfaceName_ == interfaceName) { + auto mapIter = props.find(propertyName_); if (mapIter != props.end()) { notifyListeners(mapIter->second.contained_.template get<ValueType>()); } @@ -423,15 +423,13 @@ protected: 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_; - + const std::string interfaceName_; + const std::string propertyName_; bool subSet_; - + DBusEvent<SignalEvent> internalEvent_; }; template <typename _AttributeType, typename _DBusProxyType = DBusProxy> @@ -447,10 +445,7 @@ class DBusFreedesktopObservableAttribute: public _AttributeType { const char* propertyName, _AttributeTypeArguments... arguments): _AttributeType(dbusProxy, interfaceName, propertyName, arguments...), - propertyName_(propertyName), - interfaceName_(interfaceName), externalChangedEvent_(dbusProxy, interfaceName, propertyName) { - } ChangedEvent& getChangedEvent() { @@ -459,8 +454,6 @@ class DBusFreedesktopObservableAttribute: public _AttributeType { protected: LegacyEvent<ChangedEvent, _DBusProxyType> externalChangedEvent_; - const char * propertyName_; - const char * interfaceName_; }; template< class, class > @@ -484,8 +477,8 @@ protected: void onInternalEvent(const std::string& interfaceName, const std::unordered_map<std::string, DBusLegacyVariantWrapper<ValueType> >& props, const std::vector<std::string>& invalid) { - if (std::string(interfaceName_) == interfaceName) { - auto mapIter = props.find(std::string(propertyName_)); + if (interfaceName_ == interfaceName) { + auto mapIter = props.find(propertyName_); if (mapIter != props.end()) { notifyListeners(mapIter->second.contained_); } @@ -519,8 +512,8 @@ protected: typename DBusEvent<SignalEvent>::Subscription sub; - const char* interfaceName_; - const char* propertyName_; + const std::string interfaceName_; + const std::string propertyName_; bool subSet_; @@ -539,10 +532,7 @@ class DBusFreedesktopUnionObservableAttribute: public _AttributeType { const char* propertyName, _AttributeTypeArguments... arguments): _AttributeType(dbusProxy, interfaceName, propertyName, arguments...), - propertyName_(propertyName), - interfaceName_(interfaceName), externalChangedEvent_(dbusProxy, interfaceName, propertyName) { - } ChangedEvent& getChangedEvent() { @@ -551,8 +541,6 @@ class DBusFreedesktopUnionObservableAttribute: public _AttributeType { protected: LegacyUnionEvent<ChangedEvent, _DBusProxyType> externalChangedEvent_; - const char * propertyName_; - const char * interfaceName_; }; } // namespace DBus diff --git a/src/CommonAPI/DBus/DBusEvent.h b/src/CommonAPI/DBus/DBusEvent.h index ecd8735..7b43ba2 100644 --- a/src/CommonAPI/DBus/DBusEvent.h +++ b/src/CommonAPI/DBus/DBusEvent.h @@ -98,8 +98,8 @@ class DBusEvent: public _EventType, public DBusProxyConnection::DBusSignalHandle _DBusProxy& dbusProxy_; const char* eventName_; const char* eventSignature_; - const char* interfaceName_; const char* objectPath_; + const char* interfaceName_; DBusProxyConnection::DBusSignalHandlerToken subscription_; }; diff --git a/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp b/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp new file mode 100644 index 0000000..9823af5 --- /dev/null +++ b/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.cpp @@ -0,0 +1,110 @@ +/* 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/. */ +#include "DBusFreedesktopPropertiesStub.h" +#include "DBusStubAdapter.h" +#include "DBusServicePublisher.h" +#include "DBusOutputStream.h" +#include "DBusInputStream.h" + +#include <cassert> +#include <vector> + +namespace CommonAPI { +namespace DBus { + +DBusFreedesktopPropertiesStub::DBusFreedesktopPropertiesStub(const std::string& dbusObjectPath, + const std::string& dbusInterfaceName, + const std::shared_ptr<DBusProxyConnection>& dbusConnection, + const std::shared_ptr<DBusStubAdapter>& dbusStubAdapter) : + dbusObjectPath_(dbusObjectPath), + dbusConnection_(dbusConnection), + dbusStubAdapter_(dbusStubAdapter) { + assert(!dbusObjectPath.empty()); + assert(dbusObjectPath[0] == '/'); + assert(dbusConnection); + + dbusInterfacesLock_.lock(); + if(managedInterfaces_.find(dbusInterfaceName) == managedInterfaces_.end()) { + managedInterfaces_.insert({dbusInterfaceName, dbusStubAdapter}); + } + dbusInterfacesLock_.unlock(); + +} + +DBusFreedesktopPropertiesStub::~DBusFreedesktopPropertiesStub() { + // TODO: maybee some deregistration etc. +} + +const char* DBusFreedesktopPropertiesStub::getMethodsDBusIntrospectionXmlData() const { + return "<interface name=\"org.freedesktop.DBus.Properties\">\n" + "<method name=\"Get\">\n" + "<arg type=\"s\" name=\"interface_name\" direction=\"in\"/>\n" + "<arg type=\"s\" name=\"property_name\" direction=\"in\"/>\n" + "<arg type=\"v\" name=\"value\" direction=\"out\"/>\n" + "</method>\n" + "<method name=\"GetAll\">\n" + "<arg type=\"s\" name=\"interface_name\" direction=\"in\"/>\n" + "<arg type=\"a{sv}\" name=\"properties\" direction=\"out\"/>\n" + "</method>\n" + "<method name=\"Set\">\n" + "<arg type=\"s\" name=\"interface_name\" direction=\"in\"/>\n" + "<arg type=\"s\" name=\"property_name\" direction=\"in\"/>\n" + "<arg type=\"v\" name=\"value\" direction=\"in\"/>\n" + "</method>\n" + "<signal name=\"PropertiesChanged\">\n" + "<arg type=\"s\" name=\"interface_name\"/>\n" + "<arg type=\"a{sv}\" name=\"changed_properties\"/>\n" + "<arg type=\"as\" name=\"invalidated_properties\"/>\n" + "</signal>\n" + "</interface>\n"; +} + +bool DBusFreedesktopPropertiesStub::onInterfaceDBusMessage(const DBusMessage& dbusMessage) { + auto dbusConnection = dbusConnection_.lock(); + + if (!dbusConnection || !dbusConnection->isConnected()) { + return false; + } + + if (!dbusMessage.isMethodCallType() || !(dbusMessage.hasMemberName("Get") || dbusMessage.hasMemberName("GetAll") || dbusMessage.hasMemberName("Set"))) { + return false; + } + + DBusInputStream dbusInputStream(dbusMessage); + std::string interfaceName; + + dbusInputStream >> interfaceName; + + if(dbusInputStream.hasError()) { + return false; + } + + std::lock_guard<std::mutex> dbusInterfacesLock(dbusInterfacesLock_); + + auto managedInterfacesIterator = managedInterfaces_.find(interfaceName); + + if(managedInterfacesIterator == managedInterfaces_.end()) { + return false; + } + + return managedInterfacesIterator->second->onInterfaceDBusFreedesktopPropertiesMessage(dbusMessage); +} + +const bool DBusFreedesktopPropertiesStub::hasFreedesktopProperties() { + return false; +} + +const std::string& DBusFreedesktopPropertiesStub::getDBusObjectPath() const { + return dbusObjectPath_; +} + +const char* DBusFreedesktopPropertiesStub::getInterfaceName() { + return "org.freedesktop.DBus.Properties"; +} + +} // namespace DBus +} // namespace CommonAPI diff --git a/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.h b/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.h new file mode 100644 index 0000000..c6b38a0 --- /dev/null +++ b/src/CommonAPI/DBus/DBusFreedesktopPropertiesStub.h @@ -0,0 +1,60 @@ +/* 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/. */ + +#if !defined (COMMONAPI_INTERNAL_COMPILATION) +#error "Only <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents." +#endif + +#ifndef COMMONAPI_DBUS_DBUS_FREEDESKTOP_PROPERTIES_STUB_H_ +#define COMMONAPI_DBUS_DBUS_FREEDESKTOP_PROPERTIES_STUB_H_ + +#include "DBusInterfaceHandler.h" + +#include <memory> +#include <mutex> +#include <string> + +namespace CommonAPI { +namespace DBus { + +class DBusStubAdapter; + +/** + * Stub for standard <a href="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties">org.freedesktop.dbus.Properties</a> interface. + * + * DBusFreedesktopPropertiesStub gets the DBusStubAdapter for handling the actual properties with instantiation. + */ +class DBusFreedesktopPropertiesStub: public DBusInterfaceHandler { +public: + DBusFreedesktopPropertiesStub(const std::string& dbusObjectPath, + const std::string& dbusInterfaceName, + const std::shared_ptr<DBusProxyConnection>&, + const std::shared_ptr<DBusStubAdapter>& dbusStubAdapter); + + virtual ~DBusFreedesktopPropertiesStub(); + + const std::string& getDBusObjectPath() const; + static const char* getInterfaceName(); + + virtual const char* getMethodsDBusIntrospectionXmlData() const; + virtual bool onInterfaceDBusMessage(const DBusMessage& dbusMessage); + virtual const bool hasFreedesktopProperties(); +private: + std::string dbusObjectPath_; + std::weak_ptr<DBusProxyConnection> dbusConnection_; + std::shared_ptr<DBusStubAdapter> dbusStubAdapter_; + + typedef std::unordered_map<std::string, std::shared_ptr<DBusStubAdapter>> DBusInterfacesMap; + DBusInterfacesMap managedInterfaces_; + + std::mutex dbusInterfacesLock_; +}; + +} // namespace DBus +} // namespace CommonAPI + +#endif // COMMONAPI_DBUS_DBUS_FREEDESKTOP_PROPERTIES_STUB_H_ diff --git a/src/CommonAPI/DBus/DBusFunctionalHash.cpp b/src/CommonAPI/DBus/DBusFunctionalHash.cpp index bdc5daf..a3a334a 100644 --- a/src/CommonAPI/DBus/DBusFunctionalHash.cpp +++ b/src/CommonAPI/DBus/DBusFunctionalHash.cpp @@ -11,56 +11,58 @@ #include <cassert> #include <cstring> - /* * @see http://code.google.com/p/smhasher/ */ #define SMHASHER_SEED_VALUE 0xc70f6907UL - namespace std { -size_t hash< pair<const char*, const char*> >::operator()(const pair<const char*, const char*>& t) const { - const char* a = t.first; - const char* b = t.second; +size_t hash<pair<const char*, const char*> >::operator()(const pair<const char*, const char*>& t) const { + const char* a = t.first; + const char* b = t.second; - assert(a); - assert(b); + assert(a); + assert(b); - uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE); - MurmurHash3_x86_32(a, strlen(a), seed, &seed); - MurmurHash3_x86_32(b, strlen(b), seed, &seed); + uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE); + MurmurHash3_x86_32(a, strlen(a), seed, &seed); + MurmurHash3_x86_32(b, strlen(b), seed, &seed); - return static_cast<size_t>(seed); + return static_cast<size_t>(seed); } +size_t hash<const char*>::operator()(const char* const t) const { + uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE); + MurmurHash3_x86_32(t, strlen(t), seed, &seed); + return static_cast<size_t>(seed); +} -size_t hash< pair<string, string> >::operator()(const pair<string, string>& t) const { - const string& a = t.first; - const string& b = t.second; +size_t hash<pair<string, string> >::operator()(const pair<string, string>& t) const { + const string& a = t.first; + const string& b = t.second; - uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE); - MurmurHash3_x86_32(a.c_str(), a.length(), seed, &seed); - MurmurHash3_x86_32(b.c_str(), b.length(), seed, &seed); + uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE); + MurmurHash3_x86_32(a.c_str(), a.length(), seed, &seed); + MurmurHash3_x86_32(b.c_str(), b.length(), seed, &seed); - return static_cast<size_t>(seed); + return static_cast<size_t>(seed); } +size_t hash<tuple<string, string, string> >::operator()(const tuple<string, string, string>& t) const { + const string& a = get<0>(t); + const string& b = get<1>(t); + const string& c = get<2>(t); -size_t hash< tuple<string, string, string> >::operator()(const tuple<string, string, string>& t) const { - const string& a = get<0>(t); - const string& b = get<1>(t); - const string& c = get<2>(t); - - uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE); - MurmurHash3_x86_32(a.c_str(), a.length(), seed, &seed); - MurmurHash3_x86_32(b.c_str(), b.length(), seed, &seed); - MurmurHash3_x86_32(c.c_str(), c.length(), seed, &seed); + uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE); + MurmurHash3_x86_32(a.c_str(), a.length(), seed, &seed); + MurmurHash3_x86_32(b.c_str(), b.length(), seed, &seed); + MurmurHash3_x86_32(c.c_str(), c.length(), seed, &seed); - return static_cast<size_t>(seed); + return static_cast<size_t>(seed); } -size_t hash< tuple<string, string, string, bool> >::operator()(const tuple<string, string, string, bool>& t) const { +size_t hash<tuple<string, string, string, bool> >::operator()(const tuple<string, string, string, bool>& t) const { const string& a = get<0>(t); const string& b = get<1>(t); const string& c = get<2>(t); @@ -75,7 +77,7 @@ size_t hash< tuple<string, string, string, bool> >::operator()(const tuple<strin return static_cast<size_t>(seed); } -size_t hash< tuple<string, string, string, int> >::operator()(const tuple<string, string, string, int>& t) const { +size_t hash<tuple<string, string, string, int> >::operator()(const tuple<string, string, string, int>& t) const { const string& a = get<0>(t); const string& b = get<1>(t); const string& c = get<2>(t); @@ -90,29 +92,27 @@ size_t hash< tuple<string, string, string, int> >::operator()(const tuple<string return static_cast<size_t>(seed); } +size_t hash<tuple<string, string, string, string> >::operator()(const tuple<string, string, string, string>& t) const { + const string& a = get<0>(t); + const string& b = get<1>(t); + const string& c = get<2>(t); + const string& d = get<3>(t); -size_t hash< tuple<string, string, string, string> >::operator()(const tuple<string, string, string, string>& t) const { - const string& a = get<0>(t); - const string& b = get<1>(t); - const string& c = get<2>(t); - const string& d = get<3>(t); - - uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE); - MurmurHash3_x86_32(a.c_str(), a.length(), seed, &seed); - MurmurHash3_x86_32(b.c_str(), b.length(), seed, &seed); - MurmurHash3_x86_32(c.c_str(), c.length(), seed, &seed); - MurmurHash3_x86_32(d.c_str(), d.length(), seed, &seed); + uint32_t seed = static_cast<uint32_t>(SMHASHER_SEED_VALUE); + MurmurHash3_x86_32(a.c_str(), a.length(), seed, &seed); + MurmurHash3_x86_32(b.c_str(), b.length(), seed, &seed); + MurmurHash3_x86_32(c.c_str(), c.length(), seed, &seed); + MurmurHash3_x86_32(d.c_str(), d.length(), seed, &seed); - return static_cast<size_t>(seed); + return static_cast<size_t>(seed); } +bool equal_to<pair<const char*, const char*> >::operator()(const pair<const char*, const char*>& a, + const pair<const char*, const char*>& b) const { + if (a.first == b.first && a.second == b.second) + return true; -bool equal_to< pair<const char*, const char*> >::operator()(const pair<const char*, const char*>& a, - const pair<const char*, const char*>& b) const { - if (a.first == b.first && a.second == b.second) - return true; - - return !strcmp(a.first, b.first) && !strcmp(a.second, b.second); + return !strcmp(a.first, b.first) && !strcmp(a.second, b.second); } } // namespace std diff --git a/src/CommonAPI/DBus/DBusFunctionalHash.h b/src/CommonAPI/DBus/DBusFunctionalHash.h index 2e81ae1..7ffec89 100644 --- a/src/CommonAPI/DBus/DBusFunctionalHash.h +++ b/src/CommonAPI/DBus/DBusFunctionalHash.h @@ -19,26 +19,31 @@ namespace std { template<> -struct hash< pair<const char*, const char*> >: - public unary_function< pair<const char*, const char*>, size_t > { +struct hash<pair<const char*, const char*> > : + public unary_function<pair<const char*, const char*>, size_t> { - size_t operator()(const pair<const char*, const char*>& t) const; + size_t operator()(const pair<const char*, const char*>& t) const; }; - template<> -struct hash< pair<string, string> >: - public unary_function< pair<string, string>, size_t > { +struct hash<const char*> : + public unary_function<const char*, size_t> { - size_t operator()(const pair<string, string>& t) const; + size_t operator()(const char* const t) const; }; +template<> +struct hash<pair<string, string> > : + public unary_function<pair<string, string>, size_t> { + + size_t operator()(const pair<string, string>& t) const; +}; template<> -struct hash< tuple<string, string, string> >: - public unary_function< tuple<string, string, string>, size_t > { +struct hash<tuple<string, string, string> > : + public unary_function<tuple<string, string, string>, size_t> { - size_t operator()(const tuple<string, string, string>& t) const; + size_t operator()(const tuple<string, string, string>& t) const; }; template<> diff --git a/src/CommonAPI/DBus/DBusInterfaceHandler.h b/src/CommonAPI/DBus/DBusInterfaceHandler.h index 92b65fa..1ee2cb1 100644 --- a/src/CommonAPI/DBus/DBusInterfaceHandler.h +++ b/src/CommonAPI/DBus/DBusInterfaceHandler.h @@ -22,6 +22,8 @@ class DBusInterfaceHandler { virtual const char* getMethodsDBusIntrospectionXmlData() const = 0; virtual bool onInterfaceDBusMessage(const DBusMessage& dbusMessage) = 0; + + virtual const bool hasFreedesktopProperties() = 0; }; } // namespace dbus diff --git a/src/CommonAPI/DBus/DBusLegacyVariant.h b/src/CommonAPI/DBus/DBusLegacyVariant.h index 0ac9df6..ec3b5c9 100644 --- a/src/CommonAPI/DBus/DBusLegacyVariant.h +++ b/src/CommonAPI/DBus/DBusLegacyVariant.h @@ -43,7 +43,11 @@ struct ApplyIndexForStringVisitor<Visitor, Variant, _Type, _Types...> { DBusTypeOutputStream typeStream_; TypeWriter<_Type>::writeType(typeStream_); const std::string sig = typeStream_.retrieveSignature(); +#ifdef WIN32 + if (visitor.operator()<_Type>(sig)) { +#else if (visitor.template operator()<_Type>(sig)) { +#endif return index; } else { return ApplyIndexForStringVisitor<Visitor, Variant, _Types...>::visit(visitor, diff --git a/src/CommonAPI/DBus/DBusObjectManager.cpp b/src/CommonAPI/DBus/DBusObjectManager.cpp index 2feff75..df43bf0 100644 --- a/src/CommonAPI/DBus/DBusObjectManager.cpp +++ b/src/CommonAPI/DBus/DBusObjectManager.cpp @@ -10,6 +10,8 @@ #include "DBusOutputStream.h" #include "DBusUtils.h" +#include "DBusFreedesktopPropertiesStub.h" + #include <CommonAPI/utils.h> #include <dbus/dbus-protocol.h> @@ -54,6 +56,20 @@ bool DBusObjectManager::registerDBusStubAdapter(std::shared_ptr<DBusStubAdapter> objectPathLock_.lock(); isRegistrationSuccessful = addDBusInterfaceHandler(dbusStubAdapterHandlerPath, dbusStubAdapter); + if(isRegistrationSuccessful && dbusStubAdapter->hasFreedesktopProperties()) { + const std::shared_ptr<DBusFreedesktopPropertiesStub> dbusFreedesktopPropertiesStub = + std::make_shared<DBusFreedesktopPropertiesStub>(dbusStubAdapterObjectPath, + dbusStubAdapterInterfaceName, + dbusStubAdapter->getDBusConnection(), + dbusStubAdapter); + isRegistrationSuccessful = isRegistrationSuccessful + && addDBusInterfaceHandler( + {dbusFreedesktopPropertiesStub->getDBusObjectPath(), + dbusFreedesktopPropertiesStub->getInterfaceName() + }, + dbusFreedesktopPropertiesStub); + } + if (isRegistrationSuccessful && dbusStubAdapter->isManagingInterface()) { auto managerStubIterator = managerStubs_.find(dbusStubAdapterObjectPath); const bool managerStubExists = managerStubIterator != managerStubs_.end(); @@ -252,7 +268,6 @@ bool DBusObjectManager::onIntrospectableInterfaceDBusMessage(const DBusMessage& << dbusStubAdapterBase->getMethodsDBusIntrospectionXmlData() << "\n" "</interface>\n"; nodeSet.insert(elems.back()); - //break; } else { if (dbusMessage.hasObjectPath("/") && elems.size() > 1) { if (nodeSet.find(elems[1]) == nodeSet.end()) { diff --git a/src/CommonAPI/DBus/DBusObjectManager.h b/src/CommonAPI/DBus/DBusObjectManager.h index db63e3e..6ce6e6c 100644 --- a/src/CommonAPI/DBus/DBusObjectManager.h +++ b/src/CommonAPI/DBus/DBusObjectManager.h @@ -50,6 +50,8 @@ class DBusObjectManager { std::shared_ptr<DBusInterfaceHandler> dbusInterfaceHandler); bool onIntrospectableInterfaceDBusMessage(const DBusMessage& callMessage); + bool onFreedesktopPropertiesDBusMessage(const DBusMessage& callMessage); + typedef std::unordered_map<DBusInterfaceHandlerPath, std::shared_ptr<DBusInterfaceHandler>> DBusRegisteredObjectsTable; DBusRegisteredObjectsTable dbusRegisteredObjectsTable_; diff --git a/src/CommonAPI/DBus/DBusObjectManagerStub.cpp b/src/CommonAPI/DBus/DBusObjectManagerStub.cpp index 7c2237e..970f366 100644 --- a/src/CommonAPI/DBus/DBusObjectManagerStub.cpp +++ b/src/CommonAPI/DBus/DBusObjectManagerStub.cpp @@ -186,6 +186,10 @@ bool DBusObjectManagerStub::emitInterfacesAddedSignal(std::shared_ptr<DBusStubAd dbusInterfacesAndPropertiesDict.insert({ getInterfaceName(), DBusPropertiesChangedDict() }); } + if (dbusStubAdapter->hasFreedesktopProperties()) { + dbusInterfacesAndPropertiesDict.insert({ "org.freedesktop.DBus.Properties", DBusPropertiesChangedDict() }); + } + dbusOutputStream << dbusStubObjectPath; dbusOutputStream << dbusInterfacesAndPropertiesDict; dbusOutputStream.flush(); @@ -280,6 +284,10 @@ bool DBusObjectManagerStub::onInterfaceDBusMessage(const DBusMessage& dbusMessag } +const bool DBusObjectManagerStub::hasFreedesktopProperties() { + return false; +} + const std::string& DBusObjectManagerStub::getDBusObjectPath() const { return dbusObjectPath_; } diff --git a/src/CommonAPI/DBus/DBusObjectManagerStub.h b/src/CommonAPI/DBus/DBusObjectManagerStub.h index 8a990ab..7de54f2 100644 --- a/src/CommonAPI/DBus/DBusObjectManagerStub.h +++ b/src/CommonAPI/DBus/DBusObjectManagerStub.h @@ -99,6 +99,7 @@ class DBusObjectManagerStub: public DBusInterfaceHandler { virtual const char* getMethodsDBusIntrospectionXmlData() const; virtual bool onInterfaceDBusMessage(const DBusMessage& dbusMessage); + virtual const bool hasFreedesktopProperties(); private: bool registerDBusStubAdapter(std::shared_ptr<DBusStubAdapter> dbusStubAdapter); diff --git a/src/CommonAPI/DBus/DBusOutputStream.h b/src/CommonAPI/DBus/DBusOutputStream.h index 49b7ccd..51e5f2f 100644 --- a/src/CommonAPI/DBus/DBusOutputStream.h +++ b/src/CommonAPI/DBus/DBusOutputStream.h @@ -133,6 +133,10 @@ public: signature_.append("(yv)"); } + void writeLegacyVariantType() { + signature_.append("v"); + } + virtual std::string retrieveSignature() { return std::move(signature_); } diff --git a/src/CommonAPI/DBus/DBusStubAdapter.cpp b/src/CommonAPI/DBus/DBusStubAdapter.cpp index 6b97c0b..a27bf40 100644 --- a/src/CommonAPI/DBus/DBusStubAdapter.cpp +++ b/src/CommonAPI/DBus/DBusStubAdapter.cpp @@ -69,6 +69,10 @@ const std::string& DBusStubAdapter::getInstanceId() const { return commonApiParticipantId_; } +const bool DBusStubAdapter::hasFreedesktopProperties() { + return false; +} + const bool DBusStubAdapter::isManagingInterface() { return isManagingInterface_; } diff --git a/src/CommonAPI/DBus/DBusStubAdapter.h b/src/CommonAPI/DBus/DBusStubAdapter.h index fa7a377..3b6bfb6 100644 --- a/src/CommonAPI/DBus/DBusStubAdapter.h +++ b/src/CommonAPI/DBus/DBusStubAdapter.h @@ -59,7 +59,8 @@ class DBusStubAdapter: virtual public CommonAPI::StubAdapter, public DBusInterfa virtual bool onInterfaceDBusMessage(const DBusMessage& dbusMessage) = 0; virtual void deactivateManagedInstances() = 0; - + virtual const bool hasFreedesktopProperties(); + virtual bool onInterfaceDBusFreedesktopPropertiesMessage(const DBusMessage& dbusMessage) = 0; protected: const std::string commonApiDomain_; diff --git a/src/CommonAPI/DBus/DBusStubAdapterHelper.h b/src/CommonAPI/DBus/DBusStubAdapterHelper.h index e2cbd13..dbac232 100644 --- a/src/CommonAPI/DBus/DBusStubAdapterHelper.h +++ b/src/CommonAPI/DBus/DBusStubAdapterHelper.h @@ -12,12 +12,15 @@ #ifndef COMMONAPI_DBUS_DBUS_STUB_ADAPTER_HELPER_H_ #define COMMONAPI_DBUS_DBUS_STUB_ADAPTER_HELPER_H_ +#include <CommonAPI/SerializableVariant.h> + #include "DBusStubAdapter.h" #include "DBusInputStream.h" #include "DBusOutputStream.h" #include "DBusHelper.h" #include "DBusSerializableArguments.h" #include "DBusClientId.h" +#include "DBusLegacyVariant.h" #include <memory> #include <initializer_list> @@ -33,6 +36,21 @@ public: }; template <typename _StubClass> +class DBusGetFreedesktopAttributeStubDispatcherBase; + +struct DBusAttributeDispatcherStruct { + StubDispatcherBase* getter; + StubDispatcherBase* setter; + + DBusAttributeDispatcherStruct(StubDispatcherBase* g, StubDispatcherBase* s) { + getter = g; + setter = s; + } +}; + +typedef std::unordered_map<std::string, DBusAttributeDispatcherStruct> StubAttributeTable; + +template <typename _StubClass> class DBusStubAdapterHelper: public virtual DBusStubAdapter { public: typedef typename _StubClass::StubAdapterType StubAdapterType; @@ -57,7 +75,8 @@ class DBusStubAdapterHelper: public virtual DBusStubAdapter { const std::shared_ptr<_StubClass>& stub, const bool isManagingInterface): DBusStubAdapter(factory, commonApiAddress, dbusInterfaceName, dbusBusName, dbusObjectPath, dbusConnection, isManagingInterface), - stub_(stub) { + stub_(stub), + remoteEventHandler_(NULL) { } virtual ~DBusStubAdapterHelper() { @@ -104,10 +123,118 @@ class DBusStubAdapterHelper: public virtual DBusStubAdapter { return dbusMessageHandled; } + virtual bool onInterfaceDBusFreedesktopPropertiesMessage(const DBusMessage& dbusMessage) { + DBusInputStream dbusInputStream(dbusMessage); + + if(dbusMessage.hasMemberName("Get")) { + return handleFreedesktopGet(dbusMessage, dbusInputStream); + } else if(dbusMessage.hasMemberName("Set")) { + return handleFreedesktopSet(dbusMessage, dbusInputStream); + } else if(dbusMessage.hasMemberName("GetAll")) { + return handleFreedesktopGetAll(dbusMessage, dbusInputStream); + } + + return false; + } + virtual const StubDispatcherTable& getStubDispatcherTable() = 0; + virtual const StubAttributeTable& getStubAttributeTable() = 0; std::weak_ptr<_StubClass> stub_; RemoteEventHandlerType* remoteEventHandler_; + private: + bool handleFreedesktopGet(const DBusMessage& dbusMessage, DBusInputStream& dbusInputStream) { + std::string interfaceName; + std::string attributeName; + dbusInputStream >> interfaceName; + dbusInputStream >> attributeName; + + if (dbusInputStream.hasError()) { + return false; + } + + auto attributeDispatcherIterator = getStubAttributeTable().find(attributeName); + // check, if we want to access with a valid attribute name + if (attributeDispatcherIterator == getStubAttributeTable().end()) { + return false; + } + + //To prevent the destruction of the stub whilst still handling a message + auto stubSafety = stub_.lock(); + if (stubSafety) { + StubDispatcher* getterDispatcher = static_cast<StubDispatcher*>(attributeDispatcherIterator->second.getter); + assert(getterDispatcher != NULL); // all attributes have at least a getter + return (getterDispatcher->dispatchDBusMessage(dbusMessage, stubSafety, *this)); + } + + return false; + } + + bool handleFreedesktopSet(const DBusMessage& dbusMessage, DBusInputStream& dbusInputStream) { + std::string interfaceName; + std::string attributeName; + dbusInputStream >> interfaceName; + dbusInputStream >> attributeName; + + if(dbusInputStream.hasError()) { + return false; + } + + auto attributeDispatcherIterator = getStubAttributeTable().find(attributeName); + // check, if we want to access with a valid attribute name + if(attributeDispatcherIterator == getStubAttributeTable().end()) { + return false; + } + + //To prevent the destruction of the stub whilst still handling a message + auto stubSafety = stub_.lock(); + if (stubSafety) { + StubDispatcher* setterDispatcher = static_cast<StubDispatcher*>(attributeDispatcherIterator->second.setter); + + if(setterDispatcher == NULL) { // readonly attributes do not have a setter + return false; + } + + return(setterDispatcher->dispatchDBusMessage(dbusMessage, stubSafety, *this)); + } + + return false; + } + + bool handleFreedesktopGetAll(const DBusMessage& dbusMessage, DBusInputStream& dbusInputStream) { + std::string interfaceName; + dbusInputStream >> interfaceName; + + if(dbusInputStream.hasError()) { + return false; + } + + DBusMessage dbusMessageReply = dbusMessage.createMethodReturn("a{sv}"); + DBusOutputStream dbusOutputStream(dbusMessageReply); + dbusOutputStream.beginWriteVectorOfSerializableStructs(getStubAttributeTable().size()); + + std::shared_ptr<DBusClientId> clientId = std::make_shared<DBusClientId>(std::string(dbusMessage.getSenderName())); + + auto stubSafety = stub_.lock(); + + for(auto attributeDispatcherIterator = getStubAttributeTable().begin(); attributeDispatcherIterator != getStubAttributeTable().end(); attributeDispatcherIterator++) { + //To prevent the destruction of the stub whilst still handling a message + if (stubSafety) { + DBusGetFreedesktopAttributeStubDispatcherBase<_StubClass>* const getterDispatcher = dynamic_cast<DBusGetFreedesktopAttributeStubDispatcherBase<_StubClass>*>(attributeDispatcherIterator->second.getter); + + if(getterDispatcher == NULL) { // readonly attributes do not have a setter + return false; + } + + dbusOutputStream << attributeDispatcherIterator->first; + getterDispatcher->dispatchDBusMessageAndAppendReply(dbusMessage, stubSafety, dbusOutputStream, clientId); + } + } + + dbusOutputStream.endWriteVector(); + dbusOutputStream.flush(); + return getDBusConnection()->sendDBusMessage(dbusMessageReply); + } }; template< class > @@ -115,14 +242,16 @@ struct DBusStubSignalHelper; template<template<class ...> class _In, class... _InArgs> struct DBusStubSignalHelper<_In<_InArgs...>> { - template <typename _DBusStub = DBusStubAdapter> - static bool sendSignal(const _DBusStub& dbusStub, + + static inline bool sendSignal(const char* objectPath, + const char* interfaceName, const char* signalName, const char* signalSignature, + const std::shared_ptr<DBusProxyConnection>& dbusConnection, const _InArgs&... inArgs) { DBusMessage dbusMessage = DBusMessage::createSignal( - dbusStub.getObjectPath().c_str(), - dbusStub.getInterfaceName(), + objectPath, + interfaceName, signalName, signalSignature); @@ -135,11 +264,25 @@ struct DBusStubSignalHelper<_In<_InArgs...>> { outputStream.flush(); } - const bool dbusMessageSent = dbusStub.getDBusConnection()->sendDBusMessage(dbusMessage); + const bool dbusMessageSent = dbusConnection->sendDBusMessage(dbusMessage); return dbusMessageSent; } template <typename _DBusStub = DBusStubAdapter> + static bool sendSignal(const _DBusStub& dbusStub, + const char* signalName, + const char* signalSignature, + const _InArgs&... inArgs) { + return(sendSignal(dbusStub.getObjectPath().c_str(), + dbusStub.getInterfaceName().c_str(), + signalName, + signalSignature, + dbusStub.getDBusConnection(), + inArgs...)); + } + + + template <typename _DBusStub = DBusStubAdapter> static bool sendSignal( const char* target, const _DBusStub& dbusStub, const char* signalName, @@ -167,7 +310,68 @@ struct DBusStubSignalHelper<_In<_InArgs...>> { } }; +template< class > +struct DBusStubFreedesktopPropertiesSignalHelper; + +template<template<class ...> class _In, class _InArg> +struct DBusStubFreedesktopPropertiesSignalHelper<_In<_InArg>> { + template <typename _ValueType> + struct DBusPropertiesEntry: public CommonAPI::SerializableStruct { + std::string propertyName_; + DBusLegacyVariantWrapper<CommonAPI::Variant<_ValueType>> propertyValue_; + + DBusPropertiesEntry() = default; + DBusPropertiesEntry(const std::string& propertyName, + const DBusLegacyVariantWrapper<CommonAPI::Variant<_ValueType>>& propertyValue): + propertyName_(propertyName), + propertyValue_(propertyValue) { + }; + + virtual void readFromInputStream(CommonAPI::InputStream& inputStream) { + inputStream >> propertyName_; + inputStream >> propertyValue_; + } + + virtual void writeToOutputStream(CommonAPI::OutputStream& outputStream) const { + outputStream << propertyName_; + outputStream << propertyValue_; + } + static inline void writeToTypeOutputStream(CommonAPI::TypeOutputStream& typeOutputStream) { + typeOutputStream.writeStringType(); + typeOutputStream.writeVariantType(); + } + + }; + + template <typename _DBusStub = DBusStubAdapter> + static bool sendPropertiesChangedSignal(const _DBusStub& dbusStub, const std::string& propertyName, const _InArg& inArg) { + const std::vector<std::string> invalidatedProperties; + const std::vector<DBusPropertiesEntry<_InArg>> changedProperties = {wrapValue(propertyName, inArg)}; + + return DBusStubSignalHelper<_In<const std::string, std::vector<DBusPropertiesEntry<_InArg>>, std::vector<std::string>>>:: + sendSignal(dbusStub.getObjectPath().c_str(), + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + "sa{sv}as", + dbusStub.getDBusConnection(), + dbusStub.getInterfaceName(), + changedProperties, + invalidatedProperties); + } +private: + template <typename _ValueType> + static DBusPropertiesEntry<_ValueType> wrapValue(const std::string& propertyName, _ValueType value) { + CommonAPI::Variant<_ValueType> returnVariant(value); + + DBusLegacyVariantWrapper<CommonAPI::Variant<_ValueType>> wrappedReturnVariant; + wrappedReturnVariant.contained_ = returnVariant; + + DBusPropertiesEntry<_ValueType> returnEntry(propertyName, wrappedReturnVariant); + + return returnEntry; + } +}; template< class, class > class DBusMethodStubDispatcher; @@ -348,7 +552,7 @@ class DBusMethodWithReplyAdapterDispatcher<_StubClass, _StubAdapterClass, _In<_I template <typename _StubClass, typename _AttributeType> -class DBusGetAttributeStubDispatcher: public DBusStubAdapterHelper<_StubClass>::StubDispatcher { +class DBusGetAttributeStubDispatcher: public virtual DBusStubAdapterHelper<_StubClass>::StubDispatcher { public: typedef DBusStubAdapterHelper<_StubClass> DBusStubAdapterHelperType; typedef const _AttributeType& (_StubClass::*GetStubFunctor)(std::shared_ptr<CommonAPI::ClientId>); @@ -358,12 +562,13 @@ class DBusGetAttributeStubDispatcher: public DBusStubAdapterHelper<_StubClass>:: dbusSignature_(dbusSignature) { } + virtual ~DBusGetAttributeStubDispatcher() {}; + bool dispatchDBusMessage(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper) { return sendAttributeValueReply(dbusMessage, stub, dbusStubAdapterHelper); } - protected: - inline bool sendAttributeValueReply(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper) { + virtual bool sendAttributeValueReply(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper) { DBusMessage dbusMessageReply = dbusMessage.createMethodReturn(dbusSignature_); DBusOutputStream dbusOutputStream(dbusMessageReply); @@ -379,9 +584,53 @@ class DBusGetAttributeStubDispatcher: public DBusStubAdapterHelper<_StubClass>:: const char* dbusSignature_; }; +template <typename _StubClass> +class DBusGetFreedesktopAttributeStubDispatcherBase { +public: + virtual ~DBusGetFreedesktopAttributeStubDispatcherBase() {} + virtual void dispatchDBusMessageAndAppendReply(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusOutputStream& dbusOutputStream, const std::shared_ptr<DBusClientId>& clientId) = 0; +}; template <typename _StubClass, typename _AttributeType> -class DBusSetAttributeStubDispatcher: public DBusGetAttributeStubDispatcher<_StubClass, _AttributeType> { +class DBusGetFreedesktopAttributeStubDispatcher: public virtual DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>, public virtual DBusGetFreedesktopAttributeStubDispatcherBase<_StubClass> { +public: + typedef DBusStubAdapterHelper<_StubClass> DBusStubAdapterHelperType; + typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::GetStubFunctor GetStubFunctor; + DBusGetFreedesktopAttributeStubDispatcher(GetStubFunctor getStubFunctor) : + DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>(getStubFunctor, "v") { + } + + virtual ~DBusGetFreedesktopAttributeStubDispatcher() {}; + + void dispatchDBusMessageAndAppendReply(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusOutputStream& dbusOutputStream, const std::shared_ptr<DBusClientId>& clientId) { + CommonAPI::Variant<_AttributeType> returnVariant((stub.get()->*(DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::getStubFunctor_))(clientId)); + + DBusLegacyVariantWrapper<CommonAPI::Variant<_AttributeType>> wrappedReturnVariant; + wrappedReturnVariant.contained_ = returnVariant; + + dbusOutputStream << wrappedReturnVariant; + } +protected: + virtual bool sendAttributeValueReply(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper) { + DBusMessage dbusMessageReply = dbusMessage.createMethodReturn(DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::dbusSignature_); + DBusOutputStream dbusOutputStream(dbusMessageReply); + + std::shared_ptr<DBusClientId> clientId = std::make_shared<DBusClientId>(std::string(dbusMessage.getSenderName())); + + CommonAPI::Variant<_AttributeType> returnVariant((stub.get()->*(DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::getStubFunctor_))(clientId)); + + DBusLegacyVariantWrapper<CommonAPI::Variant<_AttributeType>> wrappedReturnVariant; + wrappedReturnVariant.contained_ = returnVariant; + dbusOutputStream << wrappedReturnVariant; + dbusOutputStream.flush(); + + return dbusStubAdapterHelper.getDBusConnection()->sendDBusMessage(dbusMessageReply); + } +}; + + +template <typename _StubClass, typename _AttributeType> +class DBusSetAttributeStubDispatcher: public virtual DBusGetAttributeStubDispatcher<_StubClass, _AttributeType> { public: typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::DBusStubAdapterHelperType DBusStubAdapterHelperType; typedef typename DBusStubAdapterHelperType::RemoteEventHandlerType RemoteEventHandlerType; @@ -399,6 +648,8 @@ class DBusSetAttributeStubDispatcher: public DBusGetAttributeStubDispatcher<_Stu onRemoteChangedFunctor_(onRemoteChangedFunctor) { } + virtual ~DBusSetAttributeStubDispatcher() {}; + bool dispatchDBusMessage(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper) { bool attributeValueChanged; @@ -412,15 +663,30 @@ class DBusSetAttributeStubDispatcher: public DBusGetAttributeStubDispatcher<_Stu } protected: + virtual _AttributeType retreiveAttributeValue(const DBusMessage& dbusMessage, bool& errorOccured) { + errorOccured = false; + + DBusInputStream dbusInputStream(dbusMessage); + _AttributeType attributeValue; + dbusInputStream >> attributeValue; + + if (dbusInputStream.hasError()) { + errorOccured = true; + } + + return attributeValue; + } + inline bool setAttributeValue(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper, bool& attributeValueChanged) { - DBusInputStream dbusInputStream(dbusMessage); - _AttributeType attributeValue; - dbusInputStream >> attributeValue; - if (dbusInputStream.hasError()) + bool errorOccured; + _AttributeType attributeValue = retreiveAttributeValue(dbusMessage, errorOccured); + + if(errorOccured) { return false; + } std::shared_ptr<DBusClientId> clientId = std::make_shared<DBusClientId>(std::string(dbusMessage.getSenderName())); @@ -441,9 +707,54 @@ class DBusSetAttributeStubDispatcher: public DBusGetAttributeStubDispatcher<_Stu const OnRemoteChangedFunctor onRemoteChangedFunctor_; }; +template <typename _StubClass, typename _AttributeType> +class DBusSetFreedesktopAttributeStubDispatcher: public virtual DBusGetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>, public virtual DBusSetAttributeStubDispatcher<_StubClass, _AttributeType> { +public: + typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::GetStubFunctor GetStubFunctor; + typedef typename DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>::DBusStubAdapterHelperType DBusStubAdapterHelperType; + typedef typename DBusStubAdapterHelperType::RemoteEventHandlerType RemoteEventHandlerType; + typedef bool (RemoteEventHandlerType::*OnRemoteSetFunctor)(std::shared_ptr<CommonAPI::ClientId>, _AttributeType); + typedef void (RemoteEventHandlerType::*OnRemoteChangedFunctor)(); + + DBusSetFreedesktopAttributeStubDispatcher(GetStubFunctor getStubFunctor, + OnRemoteSetFunctor onRemoteSetFunctor, + OnRemoteChangedFunctor onRemoteChangedFunctor) : + DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>( + getStubFunctor, + "v"), + DBusGetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>( + getStubFunctor), + DBusSetAttributeStubDispatcher<_StubClass, _AttributeType>( + getStubFunctor, + onRemoteSetFunctor, + onRemoteChangedFunctor, + "v") { + } + + virtual ~DBusSetFreedesktopAttributeStubDispatcher() {}; +protected: + virtual _AttributeType retreiveAttributeValue(const DBusMessage& dbusMessage, bool& errorOccured) { + errorOccured = false; + std::string interfaceName; + std::string attributeName; + + DBusInputStream dbusInputStream(dbusMessage); + DBusLegacyVariantWrapper<CommonAPI::Variant<_AttributeType>> variantValue; + dbusInputStream >> interfaceName; // skip over interface and attribute name + dbusInputStream >> attributeName; + dbusInputStream >> variantValue; + _AttributeType attributeValue = variantValue.contained_.template get<_AttributeType>() ; + + if (dbusInputStream.hasError()) { + errorOccured = true; + } + + return attributeValue; + } +}; template <typename _StubClass, typename _AttributeType> -class DBusSetObservableAttributeStubDispatcher: public DBusSetAttributeStubDispatcher<_StubClass, _AttributeType> { +class DBusSetObservableAttributeStubDispatcher: public virtual DBusSetAttributeStubDispatcher<_StubClass, _AttributeType> { public: typedef typename DBusSetAttributeStubDispatcher<_StubClass, _AttributeType>::DBusStubAdapterHelperType DBusStubAdapterHelperType; typedef typename DBusStubAdapterHelperType::StubAdapterType StubAdapterType; @@ -458,13 +769,16 @@ class DBusSetObservableAttributeStubDispatcher: public DBusSetAttributeStubDispa OnRemoteChangedFunctor onRemoteChangedFunctor, FireChangedFunctor fireChangedFunctor, const char* dbusSignature) : + DBusGetAttributeStubDispatcher<_StubClass, _AttributeType>(getStubFunctor, dbusSignature), DBusSetAttributeStubDispatcher<_StubClass, _AttributeType>(getStubFunctor, - onRemoteSetFunctor, - onRemoteChangedFunctor, - dbusSignature), + onRemoteSetFunctor, + onRemoteChangedFunctor, + dbusSignature), fireChangedFunctor_(fireChangedFunctor) { } + virtual ~DBusSetObservableAttributeStubDispatcher() {}; + bool dispatchDBusMessage(const DBusMessage& dbusMessage, const std::shared_ptr<_StubClass>& stub, DBusStubAdapterHelperType& dbusStubAdapterHelper) { bool attributeValueChanged; if (!this->setAttributeValue(dbusMessage, stub, dbusStubAdapterHelper, attributeValueChanged)) @@ -477,15 +791,47 @@ class DBusSetObservableAttributeStubDispatcher: public DBusSetAttributeStubDispa } return true; } - - private: - inline void fireAttributeValueChanged(std::shared_ptr<CommonAPI::ClientId> clientId, DBusStubAdapterHelperType& dbusStubAdapterHelper, const std::shared_ptr<_StubClass> stub) { +protected: + virtual void fireAttributeValueChanged(std::shared_ptr<CommonAPI::ClientId> clientId, + DBusStubAdapterHelperType& dbusStubAdapterHelper, + const std::shared_ptr<_StubClass> stub) { (stub->StubType::getStubAdapter().get()->*fireChangedFunctor_)(this->getAttributeValue(clientId, stub)); } const FireChangedFunctor fireChangedFunctor_; }; +template <typename _StubClass, typename _AttributeType> +class DBusSetFreedesktopObservableAttributeStubDispatcher: public virtual DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>, public virtual DBusSetObservableAttributeStubDispatcher<_StubClass, _AttributeType> { +public: + typedef typename DBusSetFreedesktopAttributeStubDispatcher<_StubClass, _AttributeType>::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 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") { + } +}; + } // namespace DBus } // namespace CommonAPI |