// Copyright (C) 2013-2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #if !defined (COMMONAPI_INTERNAL_COMPILATION) #error "Only can be included directly, this file may disappear or change contents." #endif #ifndef COMMONAPI_DBUS_DBUS_DAEMON_PROXY_HPP_ #define COMMONAPI_DBUS_DBUS_DAEMON_PROXY_HPP_ #include #include #include #include #include #include #include namespace CommonAPI { namespace DBus { class StaticInterfaceVersionAttribute: public InterfaceVersionAttribute { public: StaticInterfaceVersionAttribute(const uint32_t& majorValue, const uint32_t& minorValue); void getValue(CommonAPI::CallStatus& callStatus, Version &_version, const CommonAPI::CallInfo *_info) const; std::future getValueAsync(AttributeAsyncCallback _callback, const CommonAPI::CallInfo *_info); private: Version version_; }; #ifndef DBUS_DAEMON_PROXY_DEFAULT_SEND_TIMEOUT #define DBUS_DAEMON_PROXY_DEFAULT_SEND_TIMEOUT 10000 #endif static const CommonAPI::CallInfo daemonProxyInfo(DBUS_DAEMON_PROXY_DEFAULT_SEND_TIMEOUT); class DBusDaemonProxy : public DBusProxyBase, public std::enable_shared_from_this { public: typedef Event NameOwnerChangedEvent; typedef std::unordered_map PropertyDictStub; typedef std::unordered_map InterfaceToPropertyDict; typedef std::unordered_map DBusObjectToInterfaceDict; typedef std::function)> ListNamesAsyncCallback; typedef std::function NameHasOwnerAsyncCallback; typedef std::function GetManagedObjectsAsyncCallback; typedef std::function GetNameOwnerAsyncCallback; COMMONAPI_EXPORT DBusDaemonProxy(const std::shared_ptr& dbusConnection); COMMONAPI_EXPORT virtual ~DBusDaemonProxy(); COMMONAPI_EXPORT virtual bool isAvailable() const; COMMONAPI_EXPORT virtual bool isAvailableBlocking() const; COMMONAPI_EXPORT virtual std::future isAvailableAsync( isAvailableAsyncCallback _callback, const CallInfo *_info) const; COMMONAPI_EXPORT virtual ProxyStatusEvent& getProxyStatusEvent(); COMMONAPI_EXPORT virtual InterfaceVersionAttribute& getInterfaceVersionAttribute(); COMMONAPI_EXPORT void init(); COMMONAPI_EXPORT static const char* getInterfaceId(); COMMONAPI_EXPORT NameOwnerChangedEvent& getNameOwnerChangedEvent(); COMMONAPI_EXPORT void listNames(CommonAPI::CallStatus& callStatus, std::vector& busNames) const; template COMMONAPI_EXPORT std::future listNamesAsync(typename DBusProxyAsyncCallbackHandler>::Delegate& delegate) const { DBusMessage dbusMessage = createMethodCall("ListNames", ""); auto dbusMessageReplyAsyncHandler = std::move(DBusProxyAsyncCallbackHandler< DelegateObjectType, std::vector< std::string > >::create(delegate, std::tuple>())); std::future callStatusFuture; try { callStatusFuture = dbusMessageReplyAsyncHandler->getFuture(); } catch (std::exception& e) { COMMONAPI_ERROR("getNameOwnerAsync: messageReplyAsyncHandler future failed(", e.what(), ")"); } if(getDBusConnection()->sendDBusMessageWithReplyAsync( dbusMessage, std::move(dbusMessageReplyAsyncHandler), &daemonProxyInfo)) { return callStatusFuture; } else { return std::future(); } } COMMONAPI_EXPORT void nameHasOwner(const std::string& busName, CommonAPI::CallStatus& callStatus, bool& hasOwner) const; template COMMONAPI_EXPORT std::future nameHasOwnerAsync(const std::string& busName, typename DBusProxyAsyncCallbackHandler::Delegate& delegate) const { DBusMessage dbusMessage = createMethodCall("NameHasOwner", "s"); DBusOutputStream outputStream(dbusMessage); const bool success = DBusSerializableArguments::serialize(outputStream, busName); if (!success) { std::promise promise; promise.set_value(CallStatus::SERIALIZATION_ERROR); return promise.get_future(); } outputStream.flush(); auto dbusMessageReplyAsyncHandler = std::move(DBusProxyAsyncCallbackHandler< DelegateObjectType, bool >::create(delegate, std::tuple< bool >())); std::future callStatusFuture; try { callStatusFuture = dbusMessageReplyAsyncHandler->getFuture(); } catch (std::exception& e) { COMMONAPI_ERROR("getNameOwnerAsync: messageReplyAsyncHandler future failed(", e.what(), ")"); } if (getDBusConnection()->sendDBusMessageWithReplyAsync( dbusMessage, std::move(dbusMessageReplyAsyncHandler), &daemonProxyInfo)) { return callStatusFuture; } else { return std::future(); } } template COMMONAPI_EXPORT std::future getManagedObjectsAsync(const std::string& forDBusServiceName, typename DBusProxyAsyncCallbackHandler::Delegate& delegate) const { static DBusAddress address(forDBusServiceName, "/", "org.freedesktop.DBus.ObjectManager"); auto dbusMethodCallMessage = DBusMessage::createMethodCall(address, "GetManagedObjects", ""); return getDBusConnection()->sendDBusMessageWithReplyAsync( dbusMethodCallMessage, DBusProxyAsyncCallbackHandler::create( delegate, std::tuple() ), &daemonProxyInfo); } /** * Get the unique connection/bus name of the primary owner of the name given * * @param busName Name to get the owner of * @param getNameOwnerAsyncCallback callback functor * * @return CallStatus::REMOTE_ERROR if the name is unknown, otherwise CallStatus::SUCCESS and the uniq name of the owner */ template std::future getNameOwnerAsync(const std::string& busName, typename DBusProxyAsyncCallbackHandler::Delegate& delegate) const { DBusMessage dbusMessage = createMethodCall("GetNameOwner", "s"); DBusOutputStream outputStream(dbusMessage); const bool success = DBusSerializableArguments::serialize(outputStream, busName); if (!success) { std::promise promise; promise.set_value(CallStatus::SERIALIZATION_ERROR); return promise.get_future(); } outputStream.flush(); auto dbusMessageReplyAsyncHandler = std::move(DBusProxyAsyncCallbackHandler< DelegateObjectType, std::string>::create(delegate, std::tuple())); std::future callStatusFuture; try { callStatusFuture = dbusMessageReplyAsyncHandler->getFuture(); } catch (std::exception& e) { COMMONAPI_ERROR("getNameOwnerAsync: messageReplyAsyncHandler future failed(", e.what(), ")"); } if (getDBusConnection()->sendDBusMessageWithReplyAsync( dbusMessage, std::move(dbusMessageReplyAsyncHandler), &daemonProxyInfo)) { return callStatusFuture; } else { return std::future(); } } private: DBusEvent nameOwnerChangedEvent_; StaticInterfaceVersionAttribute interfaceVersionAttribute_; }; } // namespace DBus } // namespace CommonAPI #endif // COMMONAPI_DBUS_DBUS_DAEMON_PROXY_HPP_