Add support for ObjectManager and other standard D-Bus interfaces (#55)

Fixes #50
This commit is contained in:
Stanislav Angelovič
2019-05-29 22:28:15 +02:00
committed by GitHub
parent 4b0c23204d
commit 91fa35140b
36 changed files with 541 additions and 235 deletions

View File

@ -65,7 +65,7 @@ set(SDBUSCPP_PUBLIC_HDRS
${SDBUSCPP_INCLUDE_DIR}/IConnection.h
${SDBUSCPP_INCLUDE_DIR}/AdaptorInterfaces.h
${SDBUSCPP_INCLUDE_DIR}/ProxyInterfaces.h
${SDBUSCPP_INCLUDE_DIR}/Introspection.h
${SDBUSCPP_INCLUDE_DIR}/StandardInterfaces.h
${SDBUSCPP_INCLUDE_DIR}/IObject.h
${SDBUSCPP_INCLUDE_DIR}/IProxy.h
${SDBUSCPP_INCLUDE_DIR}/Message.h

View File

@ -41,6 +41,7 @@ ExternalProject_Add(LibsystemdBuildProject
COMMAND ${MESON} --buildtype=${LIBSYSTEMD_BUILD_TYPE} -Dstatic-libsystemd=pic <SOURCE_DIR> <BINARY_DIR>
BUILD_COMMAND ${BUILD_VERSION_H}
COMMAND ${NINJA} -C <BINARY_DIR> libsystemd.a
BUILD_ALWAYS 1
INSTALL_COMMAND ""
LOG_DOWNLOAD 1 LOG_UPDATE 1 LOG_CONFIGURE 1 LOG_BUILD 1)

View File

@ -551,20 +551,20 @@ namespace sdbuscpp {
class Concatenator_adaptor
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.Concatenator";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.Concatenator";
protected:
Concatenator_adaptor(sdbus::IObject& object)
: object_(object)
{
object_.registerMethod("concatenate").onInterface(interfaceName).implementedAs([this](const std::vector<int32_t>& numbers, const std::string& separator){ return this->concatenate(numbers, separator); });
object_.registerSignal("concatenated").onInterface(interfaceName).withParameters<std::string>();
object_.registerMethod("concatenate").onInterface(INTERFACE_NAME).implementedAs([this](const std::vector<int32_t>& numbers, const std::string& separator){ return this->concatenate(numbers, separator); });
object_.registerSignal("concatenated").onInterface(INTERFACE_NAME).withParameters<std::string>();
}
public:
void concatenated(const std::string& concatenatedString)
{
object_.emitSignal("concatenated").onInterface(interfaceName).withArguments(concatenatedString);
object_.emitSignal("concatenated").onInterface(INTERFACE_NAME).withArguments(concatenatedString);
}
private:
@ -601,13 +601,13 @@ namespace sdbuscpp {
class Concatenator_proxy
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.Concatenator";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.Concatenator";
protected:
Concatenator_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
proxy_.uponSignal("concatenated").onInterface(interfaceName).call([this](const std::string& concatenatedString){ this->onConcatenated(concatenatedString); });
proxy_.uponSignal("concatenated").onInterface(INTERFACE_NAME).call([this](const std::string& concatenatedString){ this->onConcatenated(concatenatedString); });
}
virtual void onConcatenated(const std::string& concatenatedString) = 0;
@ -616,7 +616,7 @@ public:
std::string concatenate(const std::vector<int32_t>& numbers, const std::string& separator)
{
std::string result;
proxy_.callMethod("concatenate").onInterface(interfaceName).withArguments(numbers, separator).storeResultsTo(result);
proxy_.callMethod("concatenate").onInterface(INTERFACE_NAME).withArguments(numbers, separator).storeResultsTo(result);
return result;
}

View File

@ -130,6 +130,30 @@ namespace sdbus {
getObject().unregister();
}
/*!
* @brief Adds an ObjectManager interface at the path of this D-Bus object
*
* Creates an ObjectManager interface at the specified object path on
* the connection. This is a convenient way to interrogate a connection
* to see what objects it has.
*
* @throws sdbus::Error in case of failure
*/
void addObjectManager()
{
getObject().addObjectManager();
}
/*!
* @brief Removes an ObjectManager interface from the path of this D-Bus object
*
* @throws sdbus::Error in case of failure
*/
void removeObjectManager()
{
getObject().removeObjectManager();
}
protected:
using base_type = AdaptorInterfaces;
};

View File

@ -220,6 +220,7 @@ namespace sdbus {
PropertySetter(IProxy& proxy, const std::string& propertyName);
PropertySetter& onInterface(const std::string& interfaceName);
template <typename _Value> void toValue(const _Value& value);
void toValue(const sdbus::Variant& value);
private:
IProxy& proxy_;

View File

@ -596,13 +596,18 @@ namespace sdbus {
template <typename _Value>
inline void PropertySetter::toValue(const _Value& value)
{
PropertySetter::toValue(sdbus::Variant{value});
}
inline void PropertySetter::toValue(const sdbus::Variant& value)
{
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when setting a property", EINVAL);
proxy_
.callMethod("Set")
.onInterface("org.freedesktop.DBus.Properties")
.withArguments(interfaceName_, propertyName_, sdbus::Variant{value});
.withArguments(interfaceName_, propertyName_, value);
}
}

View File

@ -45,6 +45,8 @@ namespace sdbus {
class IConnection
{
public:
virtual ~IConnection() = default;
/*!
* @brief Requests D-Bus name on the connection
*
@ -91,7 +93,7 @@ namespace sdbus {
virtual void leaveProcessingLoop() = 0;
/*!
* @brief Add an ObjectManager at the specified D-Bus object path
* @brief Adds an ObjectManager at the specified D-Bus object path
*
* Creates an ObjectManager interface at the specified object path on
* the connection. This is a convenient way to interrogate a connection
@ -99,13 +101,9 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
virtual void addObjectManager( const std::string& objectPath ) = 0;
inline virtual ~IConnection() = 0;
virtual void addObjectManager(const std::string& objectPath) = 0;
};
IConnection::~IConnection() {}
/*!
* @brief Creates/opens D-Bus system connection
*

View File

@ -57,6 +57,8 @@ namespace sdbus {
class IObject
{
public:
virtual ~IObject() = default;
/*!
* @brief Registers method that the object will provide on D-Bus
*
@ -192,6 +194,30 @@ namespace sdbus {
*/
virtual sdbus::IConnection& getConnection() const = 0;
/*!
* @brief Adds an ObjectManager interface at the path of this D-Bus object
*
* Creates an ObjectManager interface at the specified object path on
* the connection. This is a convenient way to interrogate a connection
* to see what objects it has.
*
* @throws sdbus::Error in case of failure
*/
virtual void addObjectManager() = 0;
/*!
* @brief Removes an ObjectManager interface from the path of this D-Bus object
*
* @throws sdbus::Error in case of failure
*/
virtual void removeObjectManager() = 0;
/*!
* @brief Tests whether ObjectManager interface is added at the path of this D-Bus object
* @return True if ObjectManager interface is there, false otherwise
*/
virtual bool hasObjectManager() const = 0;
/*!
* @brief Registers method that the object will provide on D-Bus
*
@ -287,8 +313,6 @@ namespace sdbus {
* @throws sdbus::Error in case of failure
*/
SignalEmitter emitSignal(const std::string& signalName);
virtual ~IObject() = 0;
};
inline MethodRegistrator IObject::registerMethod(const std::string& methodName)
@ -316,8 +340,6 @@ namespace sdbus {
return SignalEmitter(*this, signalName);
}
inline IObject::~IObject() {}
/*!
* @brief Creates instance representing a D-Bus object
*

View File

@ -58,6 +58,8 @@ namespace sdbus {
class IProxy
{
public:
virtual ~IProxy() = default;
/*!
* @brief Creates a method call message
*
@ -259,8 +261,6 @@ namespace sdbus {
* @throws sdbus::Error in case of failure
*/
PropertySetter setProperty(const std::string& propertyName);
virtual ~IProxy() = default;
};
inline MethodInvoker IProxy::callMethod(const std::string& methodName)

View File

@ -1,84 +0,0 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file Introspection.h
*
* Created on: Dec 13, 2016
* Project: sdbus-c++
* Description: High-level D-Bus IPC C++ library based on sd-bus
*
* This file is part of sdbus-c++.
*
* sdbus-c++ is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* sdbus-c++ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with sdbus-c++. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SDBUS_CXX_INTROSPECTION_H_
#define SDBUS_CXX_INTROSPECTION_H_
#include <sdbus-c++/IObject.h>
#include <sdbus-c++/IProxy.h>
#include <string>
namespace sdbus {
// Proxy for introspection
class introspectable_proxy
{
static constexpr const char* interfaceName = "org.freedesktop.DBus.Introspectable";
protected:
introspectable_proxy(sdbus::IProxy& object)
: object_(object)
{
}
public:
std::string Introspect()
{
std::string xml;
object_.callMethod("Introspect").onInterface(interfaceName).storeResultsTo(xml);
return xml;
}
private:
sdbus::IProxy& object_;
};
// Adaptor is not necessary if we want to rely on sdbus-provided introspection
// class introspectable_adaptor
// {
// static constexpr const char* interfaceName = "org.freedesktop.DBus.Introspectable";
//
// protected:
// introspectable_adaptor(sdbus::IObject& object)
// : object_(object)
// {
// object_.registerMethod("Introspect").onInterface(interfaceName).implementedAs([this](){ return object_.introspect(); });
// }
//
// public:
// std::string introspect()
// {
// std::string xml;
// object_.callMethod("Introspect").onInterface(interfaceName).storeResultsTo(xml);
// return xml;
// }
//
// private:
// sdbus::IObject& object_;
// };
}
#endif /* SDBUS_CXX_INTROSPECTION_H_ */

View File

@ -0,0 +1,185 @@
/**
* (C) 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
*
* @file StandardInterfaces.h
*
* Created on: Dec 13, 2016
* Project: sdbus-c++
* Description: High-level D-Bus IPC C++ library based on sd-bus
*
* This file is part of sdbus-c++.
*
* sdbus-c++ is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* sdbus-c++ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with sdbus-c++. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SDBUS_CXX_STANDARDINTERFACES_H_
#define SDBUS_CXX_STANDARDINTERFACES_H_
#include <sdbus-c++/IObject.h>
#include <sdbus-c++/IProxy.h>
#include <sdbus-c++/Types.h>
#include <string>
#include <map>
#include <vector>
namespace sdbus {
// Proxy for peer
class Peer_proxy
{
static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.Peer";
protected:
Peer_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
}
public:
void Ping()
{
proxy_.callMethod("Ping").onInterface(INTERFACE_NAME);
}
std::string GetMachineId()
{
std::string machineUUID;
proxy_.callMethod("GetMachineId").onInterface(INTERFACE_NAME).storeResultsTo(machineUUID);
return machineUUID;
}
private:
sdbus::IProxy& proxy_;
};
// Proxy for introspection
class Introspectable_proxy
{
static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.Introspectable";
protected:
Introspectable_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
}
public:
std::string Introspect()
{
std::string xml;
proxy_.callMethod("Introspect").onInterface(INTERFACE_NAME).storeResultsTo(xml);
return xml;
}
private:
sdbus::IProxy& proxy_;
};
// Proxy for properties
class Properties_proxy
{
static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.Properties";
protected:
Properties_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
proxy_
.uponSignal("PropertiesChanged")
.onInterface(INTERFACE_NAME)
.call([this]( const std::string& interfaceName
, const std::map<std::string, sdbus::Variant>& changedProperties
, const std::vector<std::string>& invalidatedProperties )
{
this->onPropertiesChanged(interfaceName, changedProperties, invalidatedProperties);
});
}
virtual void onPropertiesChanged( const std::string& interfaceName
, const std::map<std::string, sdbus::Variant>& changedProperties
, const std::vector<std::string>& invalidatedProperties ) = 0;
public:
sdbus::Variant Get(const std::string& interfaceName, const std::string& propertyName)
{
return proxy_.getProperty(propertyName).onInterface(interfaceName);
}
void Set(const std::string& interfaceName, const std::string& propertyName, const sdbus::Variant& value)
{
proxy_.setProperty(propertyName).onInterface(interfaceName).toValue(value);
}
std::map<std::string, sdbus::Variant> GetAll(const std::string& interfaceName)
{
std::map<std::string, sdbus::Variant> props;
proxy_.callMethod("GetAll").onInterface(INTERFACE_NAME).withArguments(interfaceName).storeResultsTo(props);
return props;
}
private:
sdbus::IProxy& proxy_;
};
// Proxy for object manager
class ObjectManager_proxy
{
static constexpr const char* INTERFACE_NAME = "org.freedesktop.DBus.ObjectManager";
protected:
ObjectManager_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
proxy_
.uponSignal("InterfacesAdded")
.onInterface(INTERFACE_NAME)
.call([this]( const sdbus::ObjectPath& objectPath
, const std::map<std::string, std::map<std::string, sdbus::Variant>>& interfacesAndProperties )
{
this->onInterfacesAdded(objectPath, interfacesAndProperties);
});
proxy_
.uponSignal("InterfacesRemoved")
.onInterface(INTERFACE_NAME)
.call([this]( const sdbus::ObjectPath& objectPath
, const std::vector<std::string>& interfaces )
{
this->onInterfacesRemoved(objectPath, interfaces);
});
}
virtual void onInterfacesAdded( const sdbus::ObjectPath& objectPath
, const std::map<std::string, std::map<std::string, sdbus::Variant>>& interfacesAndProperties) = 0;
virtual void onInterfacesRemoved( const sdbus::ObjectPath& objectPath
, const std::vector<std::string>& interfaces) = 0;
public:
std::map<sdbus::ObjectPath, std::map<std::string, std::map<std::string, sdbus::Variant>>> GetManagedObjects()
{
std::map<sdbus::ObjectPath, std::map<std::string, std::map<std::string, sdbus::Variant>>> objectsInterfacesAndProperties;
proxy_.callMethod("GetManagedObjects").onInterface(INTERFACE_NAME).storeResultsTo(objectsInterfacesAndProperties);
return objectsInterfacesAndProperties;
}
private:
sdbus::IProxy& proxy_;
};
// Adaptors for the above-listed standard D-Bus interfaces are not necessary because the functionality
// is provided automatically for each D-Bus object by underlying libsystemd (with the exception of
// object manager which is provided but needs to be added explicitly, see IObject::addObjectManager).
}
#endif /* SDBUS_CXX_STANDARDINTERFACES_H_ */

View File

@ -28,9 +28,10 @@
#include <sdbus-c++/IProxy.h>
#include <sdbus-c++/AdaptorInterfaces.h>
#include <sdbus-c++/ProxyInterfaces.h>
#include <sdbus-c++/StandardInterfaces.h>
#include <sdbus-c++/Message.h>
#include <sdbus-c++/MethodResult.h>
#include <sdbus-c++/Types.h>
#include <sdbus-c++/TypeTraits.h>
#include <sdbus-c++/Introspection.h>
#include <sdbus-c++/Error.h>
#include <sdbus-c++/Flags.h>

View File

@ -103,19 +103,28 @@ ISdBus& Connection::getSdBusInterface()
return *iface_.get();
}
void Connection::addObjectManager( const std::string& objectPath )
void Connection::addObjectManager(const std::string& objectPath)
{
Connection::addObjectManager(objectPath, nullptr);
}
SlotPtr Connection::addObjectManager(const std::string& objectPath, void* /*dummy*/)
{
sd_bus_slot *slot{};
auto r = iface_->sd_bus_add_object_manager( bus_.get()
, NULL
, &slot
, objectPath.c_str() );
SDBUS_THROW_ERROR_IF(r < 0, "Failed to add object manager", -r);
return {slot, [this](void *slot){ iface_->sd_bus_slot_unref((sd_bus_slot*)slot); }};
}
sd_bus_slot* Connection::addObjectVTable( const std::string& objectPath
, const std::string& interfaceName
, const sd_bus_vtable* vtable
, void* userData )
SlotPtr Connection::addObjectVTable( const std::string& objectPath
, const std::string& interfaceName
, const sd_bus_vtable* vtable
, void* userData )
{
sd_bus_slot *slot{};
@ -128,12 +137,7 @@ sd_bus_slot* Connection::addObjectVTable( const std::string& objectPath
SDBUS_THROW_ERROR_IF(r < 0, "Failed to register object vtable", -r);
return slot;
}
void Connection::removeObjectVTable(sd_bus_slot* vtableHandle)
{
iface_->sd_bus_slot_unref(vtableHandle);
return {slot, [this](void *slot){ iface_->sd_bus_slot_unref((sd_bus_slot*)slot); }};
}
MethodCall Connection::createMethodCall( const std::string& destination
@ -172,11 +176,11 @@ Signal Connection::createSignal( const std::string& objectPath
return Signal{sdbusSignal, iface_.get(), adopt_message};
}
sd_bus_slot* Connection::registerSignalHandler( const std::string& objectPath
, const std::string& interfaceName
, const std::string& signalName
, sd_bus_message_handler_t callback
, void* userData )
SlotPtr Connection::registerSignalHandler( const std::string& objectPath
, const std::string& interfaceName
, const std::string& signalName
, sd_bus_message_handler_t callback
, void* userData )
{
sd_bus_slot *slot{};
@ -185,12 +189,7 @@ sd_bus_slot* Connection::registerSignalHandler( const std::string& objectPath
SDBUS_THROW_ERROR_IF(r < 0, "Failed to register signal handler", -r);
return slot;
}
void Connection::unregisterSignalHandler(sd_bus_slot* handlerCookie)
{
iface_->sd_bus_slot_unref(handlerCookie);
return {slot, [this](void *slot){ iface_->sd_bus_slot_unref((sd_bus_slot*)slot); }};
}
sd_bus* Connection::openBus(Connection::BusType type)

View File

@ -56,31 +56,32 @@ namespace sdbus { namespace internal {
void enterProcessingLoop() override;
void enterProcessingLoopAsync() override;
void leaveProcessingLoop() override;
void addObjectManager( const std::string& objectPath ) override;
void addObjectManager(const std::string& objectPath) override;
SlotPtr addObjectManager(const std::string& objectPath, void* /*dummy*/) override;
const ISdBus& getSdBusInterface() const override;
ISdBus& getSdBusInterface() override;
sd_bus_slot* addObjectVTable( const std::string& objectPath
, const std::string& interfaceName
, const sd_bus_vtable* vtable
, void* userData ) override;
void removeObjectVTable(sd_bus_slot* vtableHandle) override;
SlotPtr addObjectVTable( const std::string& objectPath
, const std::string& interfaceName
, const sd_bus_vtable* vtable
, void* userData ) override;
MethodCall createMethodCall( const std::string& destination
, const std::string& objectPath
, const std::string& interfaceName
, const std::string& methodName ) const override;
Signal createSignal( const std::string& objectPath
, const std::string& interfaceName
, const std::string& signalName ) const override;
sd_bus_slot* registerSignalHandler( const std::string& objectPath
, const std::string& interfaceName
, const std::string& signalName
, sd_bus_message_handler_t callback
, void* userData ) override;
void unregisterSignalHandler(sd_bus_slot* handlerCookie) override;
SlotPtr registerSignalHandler( const std::string& objectPath
, const std::string& interfaceName
, const std::string& signalName
, sd_bus_message_handler_t callback
, void* userData ) override;
private:
sd_bus* openBus(Connection::BusType type);

View File

@ -29,6 +29,7 @@
#include <systemd/sd-bus.h>
#include <string>
#include <memory>
#include <functional>
// Forward declaration
namespace sdbus {
@ -44,17 +45,20 @@ namespace sdbus {
namespace sdbus {
namespace internal {
using SlotPtr = std::unique_ptr<void, std::function<void(void*)>>;
class IConnection
{
public:
virtual ~IConnection() = default;
virtual const ISdBus& getSdBusInterface() const = 0;
virtual ISdBus& getSdBusInterface() = 0;
virtual sd_bus_slot* addObjectVTable( const std::string& objectPath
, const std::string& interfaceName
, const sd_bus_vtable* vtable
, void* userData ) = 0;
virtual void removeObjectVTable(sd_bus_slot* vtableHandle) = 0;
virtual SlotPtr addObjectVTable( const std::string& objectPath
, const std::string& interfaceName
, const sd_bus_vtable* vtable
, void* userData ) = 0;
virtual MethodCall createMethodCall( const std::string& destination
, const std::string& objectPath
@ -65,17 +69,16 @@ namespace internal {
, const std::string& interfaceName
, const std::string& signalName ) const = 0;
virtual sd_bus_slot* registerSignalHandler( const std::string& objectPath
, const std::string& interfaceName
, const std::string& signalName
, sd_bus_message_handler_t callback
, void* userData ) = 0;
virtual void unregisterSignalHandler(sd_bus_slot* handlerCookie) = 0;
virtual SlotPtr registerSignalHandler( const std::string& objectPath
, const std::string& interfaceName
, const std::string& signalName
, sd_bus_message_handler_t callback
, void* userData ) = 0;
virtual void enterProcessingLoopAsync() = 0;
virtual void leaveProcessingLoop() = 0;
virtual ~IConnection() = default;
virtual SlotPtr addObjectManager(const std::string& objectPath, void* /*dummy*/ = nullptr) = 0;
};
}

View File

@ -140,6 +140,21 @@ sdbus::IConnection& Object::getConnection() const
return dynamic_cast<sdbus::IConnection&>(connection_);
}
void Object::addObjectManager()
{
objectManagerSlot_ = connection_.addObjectManager(objectPath_);
}
void Object::removeObjectManager()
{
objectManagerSlot_.reset();
}
bool Object::hasObjectManager() const
{
return objectManagerSlot_ != nullptr;
}
const std::vector<sd_bus_vtable>& Object::createInterfaceVTable(InterfaceData& interfaceData)
{
auto& vtable = interfaceData.vtable_;
@ -207,10 +222,7 @@ void Object::activateInterfaceVTable( const std::string& interfaceName
, InterfaceData& interfaceData
, const std::vector<sd_bus_vtable>& vtable )
{
// Tell, don't ask
auto slot = connection_.addObjectVTable(objectPath_, interfaceName, &vtable[0], this);
interfaceData.slot_.reset(slot);
interfaceData.slot_.get_deleter() = [this](sd_bus_slot *slot){ connection_.removeObjectVTable(slot); };
interfaceData.slot_ = connection_.addObjectVTable(objectPath_, interfaceName, &vtable[0], this);
}
int Object::sdbus_method_callback(sd_bus_message *sdbusMessage, void *userData, sd_bus_error *retError)

View File

@ -80,6 +80,10 @@ namespace internal {
sdbus::IConnection& getConnection() const override;
void addObjectManager() override;
void removeObjectManager() override;
bool hasObjectManager() const override;
private:
using InterfaceName = std::string;
struct InterfaceData
@ -112,7 +116,7 @@ namespace internal {
std::vector<sd_bus_vtable> vtable_;
Flags flags_;
std::unique_ptr<sd_bus_slot, std::function<void(sd_bus_slot*)>> slot_;
SlotPtr slot_;
};
static const std::vector<sd_bus_vtable>& createInterfaceVTable(InterfaceData& interfaceData);
@ -143,6 +147,7 @@ namespace internal {
sdbus::internal::IConnection& connection_;
std::string objectPath_;
std::map<InterfaceName, InterfaceData> interfaces_;
SlotPtr objectManagerSlot_;
};
}

View File

@ -113,13 +113,11 @@ void Proxy::registerSignalHandlers(sdbus::internal::IConnection& connection)
{
const auto& signalName = signalItem.first;
auto& slot = signalItem.second.slot_;
auto* rawSlotPtr = connection.registerSignalHandler( objectPath_
, interfaceName
, signalName
, &Proxy::sdbus_signal_callback
, this );
slot.reset(rawSlotPtr);
slot.get_deleter() = [&connection](sd_bus_slot *slot){ connection.unregisterSignalHandler(slot); };
slot = connection.registerSignalHandler( objectPath_
, interfaceName
, signalName
, &Proxy::sdbus_signal_callback
, this );
}
}
}

View File

@ -27,6 +27,7 @@
#define SDBUS_CXX_INTERNAL_PROXY_H_
#include <sdbus-c++/IProxy.h>
#include "IConnection.h"
#include <systemd/sd-bus.h>
#include <string>
#include <memory>
@ -34,11 +35,6 @@
#include <unordered_map>
#include <mutex>
// Forward declarations
namespace sdbus { namespace internal {
class IConnection;
}}
namespace sdbus {
namespace internal {
@ -83,7 +79,7 @@ namespace internal {
struct SignalData
{
signal_handler callback_;
std::unique_ptr<sd_bus_slot, std::function<void(sd_bus_slot*)>> slot_;
SlotPtr slot_;
};
std::map<SignalName, SignalData> signals_;
};

View File

@ -45,6 +45,7 @@
using ::testing::Eq;
using ::testing::Gt;
using ::testing::ElementsAre;
using ::testing::SizeIs;
using namespace std::chrono_literals;
namespace
@ -65,6 +66,18 @@ public:
s_connection->releaseName(INTERFACE_NAME);
}
static void waitUntil(std::atomic<bool>& flag, std::chrono::milliseconds timeout = 1s)
{
std::chrono::milliseconds elapsed{};
std::chrono::milliseconds step{5ms};
do {
std::this_thread::sleep_for(step);
elapsed += step;
if (elapsed > timeout)
throw std::runtime_error("Waiting timed out");
} while (!flag);
}
private:
void SetUp() override
{
@ -396,30 +409,117 @@ TEST_F(SdbusTestObject, EmitsSignalWithoutRegistrationSuccesfully)
// Properties
TEST_F(SdbusTestObject, ReadsReadPropertySuccesfully)
TEST_F(SdbusTestObject, ReadsReadOnlyPropertySuccesfully)
{
ASSERT_THAT(m_proxy->state(), Eq(STRING_VALUE));
ASSERT_THAT(m_proxy->state(), Eq(DEFAULT_STATE_VALUE));
}
TEST_F(SdbusTestObject, FailsWritingToReadOnlyProperty)
{
ASSERT_THROW(m_proxy->state("new_value"), sdbus::Error);
}
TEST_F(SdbusTestObject, WritesAndReadsReadWritePropertySuccesfully)
{
uint32_t x = 42;
ASSERT_NO_THROW(m_proxy->action(x));
ASSERT_THAT(m_proxy->action(), Eq(x));
uint32_t newActionValue = 5678;
m_proxy->action(newActionValue);
ASSERT_THAT(m_proxy->action(), Eq(newActionValue));
}
TEST_F(SdbusTestObject, WritesToWritePropertySuccesfully)
// Standard D-Bus interfaces
TEST_F(SdbusTestObject, PingsViaPeerInterface)
{
auto x = true;
ASSERT_NO_THROW(m_proxy->blocking(x));
ASSERT_NO_THROW(m_proxy->Ping());
}
TEST_F(SdbusTestObject, CannotReadFromWriteProperty)
TEST_F(SdbusTestObject, AnswersMachineUuidViaPeerInterface)
{
ASSERT_THROW(m_proxy->blocking(), sdbus::Error);
ASSERT_NO_THROW(m_proxy->GetMachineId());
}
TEST_F(SdbusTestObject, AnswersXmlApiDescriptionOnIntrospection)
TEST_F(SdbusTestObject, AnswersXmlApiDescriptionViaIntrospectableInterface)
{
ASSERT_THAT(m_proxy->Introspect(), Eq(m_adaptor->getExpectedXmlApiDescription()));
}
TEST_F(SdbusTestObject, GetsPropertyViaPropertiesInterface)
{
ASSERT_THAT(m_proxy->Get(INTERFACE_NAME, "state").get<std::string>(), Eq(DEFAULT_STATE_VALUE));
}
TEST_F(SdbusTestObject, SetsPropertyViaPropertiesInterface)
{
uint32_t newActionValue = 2345;
m_proxy->Set(INTERFACE_NAME, "action", newActionValue);
ASSERT_THAT(m_proxy->action(), Eq(newActionValue));
}
TEST_F(SdbusTestObject, GetsAllPropertiesViaPropertiesInterface)
{
const auto properties = m_proxy->GetAll(INTERFACE_NAME);
ASSERT_THAT(properties, SizeIs(3));
EXPECT_THAT(properties.at("state").get<std::string>(), Eq(DEFAULT_STATE_VALUE));
EXPECT_THAT(properties.at("action").get<uint32_t>(), Eq(DEFAULT_ACTION_VALUE));
EXPECT_THAT(properties.at("blocking").get<bool>(), Eq(DEFAULT_BLOCKING_VALUE));
}
// TODO: Uncomment once we have support for PropertiesChanged signals
//TEST_F(SdbusTestObject, GetsSignalOnChangedPropertiesViaPropertiesInterface)
//{
// std::atomic<bool> signalReceived{false};
// m_proxy->m_onPropertiesChangedHandler = [&signalReceived](const std::string& interfaceName, const std::map<std::string, sdbus::Variant>& changedProperties, const std::vector<std::string>& invalidatedProperties)
// {
// EXPECT_THAT(interfaceName, Eq(INTERFACE_NAME));
// EXPECT_THAT(changedProperties, SizeIs(2));
// EXPECT_THAT(changedProperties.at("blocking").get<bool>(), Eq(false));
// EXPECT_THAT(invalidatedProperties, SizeIs(0));
// signalReceived = true;
// };
//
// m_proxy->blocking(!DEFAULT_BLOCKING_VALUE);
// waitUntil(signalReceived);
//}
TEST_F(SdbusTestObject, DoesNotProvideObjectManagerInterfaceByDefault)
{
ASSERT_THROW(m_proxy->GetManagedObjects(), sdbus::Error);
}
TEST_F(SdbusTestObject, ProvidesObjectManagerInterfaceWhenExplicitlyAdded)
{
m_adaptor->addObjectManager();
ASSERT_NO_THROW(m_proxy->GetManagedObjects());
}
TEST_F(SdbusTestObject, GetsZeroManagedObjectsIfHasNoSubPathObjects)
{
m_adaptor->addObjectManager();
const auto objectsInterfacesAndProperties = m_proxy->GetManagedObjects();
ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(0));
}
TEST_F(SdbusTestObject, GetsManagedObjectsSuccessfully)
{
m_adaptor->addObjectManager();
auto subObject1 = sdbus::createObject(*s_connection, "/sub/path1");
subObject1->registerProperty("aProperty1").onInterface("org.sdbuscpp.integrationtests.iface1").withGetter([]{return uint8_t{123};});
subObject1->finishRegistration();
auto subObject2 = sdbus::createObject(*s_connection, "/sub/path2");
subObject2->registerProperty("aProperty2").onInterface("org.sdbuscpp.integrationtests.iface2").withGetter([]{return "hi";});
subObject2->finishRegistration();
const auto objectsInterfacesAndProperties = m_proxy->GetManagedObjects();
ASSERT_THAT(objectsInterfacesAndProperties, SizeIs(2));
EXPECT_THAT(objectsInterfacesAndProperties.at("/sub/path1").at("org.sdbuscpp.integrationtests.iface1").at("aProperty1").get<uint8_t>(), Eq(123));
EXPECT_THAT(objectsInterfacesAndProperties.at("/sub/path2").at("org.sdbuscpp.integrationtests.iface2").at("aProperty2").get<std::string>(), Eq("hi"));
}

View File

@ -177,15 +177,16 @@ protected:
throw sdbus::createError(1, "A test error occurred");
}
std::string state() { return STRING_VALUE; }
std::string state() { return m_state; }
uint32_t action() { return m_action; }
void action(const uint32_t& value) { m_action = value; }
bool blocking() { return m_blocking; }
void blocking(const bool& value) { m_blocking = value; }
private:
uint32_t m_action;
bool m_blocking;
const std::string m_state{DEFAULT_STATE_VALUE};
uint32_t m_action{DEFAULT_ACTION_VALUE};
bool m_blocking{DEFAULT_BLOCKING_VALUE};
// For dont-expect-reply method call verifications
mutable std::atomic<bool> m_multiplyCalled{};

View File

@ -28,7 +28,11 @@
#include "proxy-glue.h"
class TestingProxy : public sdbus::ProxyInterfaces<::testing_proxy, sdbus::introspectable_proxy>
class TestingProxy : public sdbus::ProxyInterfaces< ::testing_proxy
, sdbus::Peer_proxy
, sdbus::Introspectable_proxy
, sdbus::Properties_proxy
, sdbus::ObjectManager_proxy >
{
public:
TestingProxy(std::string destination, std::string objectPath)
@ -73,13 +77,36 @@ protected:
m_DoOperationClientSideAsyncReplyHandler(returnValue, error);
}
private:
// Signals of standard D-Bus interfaces
void onPropertiesChanged( const std::string& interfaceName
, const std::map<std::string, sdbus::Variant>& changedProperties
, const std::vector<std::string>& invalidatedProperties ) override
{
if (m_onPropertiesChangedHandler)
m_onPropertiesChangedHandler(interfaceName, changedProperties, invalidatedProperties);
}
void onInterfacesAdded( const sdbus::ObjectPath& /*objectPath*/
, const std::map<std::string, std::map<std::string, sdbus::Variant>>& /*interfacesAndProperties*/) override
{
// Intentionally left empty
}
void onInterfacesRemoved( const sdbus::ObjectPath& /*objectPath*/
, const std::vector<std::string>& /*interfaces*/) override
{
// Intentionally left empty
}
//private:
public:
int m_simpleCallCounter{};
std::map<int32_t, std::string> m_map;
double m_variantValue;
std::map<std::string, std::string> m_signature;
std::function<void(uint32_t res, const sdbus::Error* err)> m_DoOperationClientSideAsyncReplyHandler;
std::function<void(const std::string& interfaceName, const std::map<std::string, sdbus::Variant>& changedProperties, const std::vector<std::string>& invalidatedProperties)> m_onPropertiesChangedHandler;
};

View File

@ -111,8 +111,9 @@ protected:
object_.registerSignal("signalWithVariant").onInterface(INTERFACE_NAME).withParameters<sdbus::Variant>();
object_.registerProperty("state").onInterface(INTERFACE_NAME).withGetter([this](){ return this->state(); }).markAsDeprecated().withUpdateBehavior(sdbus::Flags::CONST_PROPERTY_VALUE);
object_.registerProperty("action").onInterface(INTERFACE_NAME).withGetter([this](){ return this->action(); }).withSetter([this](const uint32_t& value){ this->action(value); }).withUpdateBehavior(sdbus::Flags::EMITS_NO_SIGNAL);
object_.registerProperty("blocking").onInterface(INTERFACE_NAME)./*withGetter([this](){ return this->blocking(); }).*/withSetter([this](const bool& value){ this->blocking(value); });
object_.registerProperty("action").onInterface(INTERFACE_NAME).withGetter([this](){ return this->action(); }).withSetter([this](const uint32_t& value){ this->action(value); }).withUpdateBehavior(sdbus::Flags::EMITS_INVALIDATION_SIGNAL);
//object_.registerProperty("blocking").onInterface(INTERFACE_NAME)./*withGetter([this](){ return this->blocking(); }).*/withSetter([this](const bool& value){ this->blocking(value); });
object_.registerProperty("blocking").onInterface(INTERFACE_NAME).withGetter([this](){ return this->blocking(); }).withSetter([this](const bool& value){ this->blocking(value); });
}
@ -294,7 +295,7 @@ R"delimiter(<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspectio
<annotation name="org.freedesktop.DBus.Deprecated" value="true"/>
</signal>
<property name="action" type="u" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="invalidates"/>
</property>
<property name="blocking" type="b" access="readwrite">
</property>

View File

@ -41,6 +41,10 @@ const std::string STRING_VALUE{"sdbus-c++-testing"};
const sdbus::Signature SIGNATURE_VALUE{"a{is}"};
const sdbus::ObjectPath OBJECT_PATH_VALUE{"/"};
const std::string DEFAULT_STATE_VALUE{"default-state-value"};
const uint32_t DEFAULT_ACTION_VALUE{999};
const bool DEFAULT_BLOCKING_VALUE{true};
constexpr const double DOUBLE_VALUE{3.24L};
#endif /* SDBUS_CPP_INTEGRATIONTESTS_DEFS_H_ */

View File

@ -211,6 +211,11 @@ public:
return object_.getProperty("state").onInterface(INTERFACE_NAME);
}
void state(const std::string& value)
{
object_.setProperty("state").onInterface(INTERFACE_NAME).toValue(value);
}
uint32_t action()
{
return object_.getProperty("action").onInterface(INTERFACE_NAME);

View File

@ -3,8 +3,8 @@
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__perftest_adaptor_h__adaptor__H__
#define __sdbuscpp__perftest_adaptor_h__adaptor__H__
#ifndef __sdbuscpp__perftests_adaptor_h__adaptor__H__
#define __sdbuscpp__perftests_adaptor_h__adaptor__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
@ -16,21 +16,21 @@ namespace sdbuscpp {
class perftests_adaptor
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.perftests";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.perftests";
protected:
perftests_adaptor(sdbus::IObject& object)
: object_(object)
{
object_.registerMethod("sendDataSignals").onInterface(interfaceName).implementedAs([this](const uint32_t& numberOfSignals, const uint32_t& signalMsgSize){ return this->sendDataSignals(numberOfSignals, signalMsgSize); });
object_.registerMethod("concatenateTwoStrings").onInterface(interfaceName).implementedAs([this](const std::string& string1, const std::string& string2){ return this->concatenateTwoStrings(string1, string2); });
object_.registerSignal("dataSignal").onInterface(interfaceName).withParameters<std::string>();
object_.registerMethod("sendDataSignals").onInterface(INTERFACE_NAME).implementedAs([this](const uint32_t& numberOfSignals, const uint32_t& signalMsgSize){ return this->sendDataSignals(numberOfSignals, signalMsgSize); });
object_.registerMethod("concatenateTwoStrings").onInterface(INTERFACE_NAME).implementedAs([this](const std::string& string1, const std::string& string2){ return this->concatenateTwoStrings(string1, string2); });
object_.registerSignal("dataSignal").onInterface(INTERFACE_NAME).withParameters<std::string>();
}
public:
void dataSignal(const std::string& data)
{
object_.emitSignal("dataSignal").onInterface(interfaceName).withArguments(data);
object_.emitSignal("dataSignal").onInterface(INTERFACE_NAME).withArguments(data);
}
private:

View File

@ -3,8 +3,8 @@
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__perftest_proxy_h__proxy__H__
#define __sdbuscpp__perftest_proxy_h__proxy__H__
#ifndef __sdbuscpp__perftests_proxy_h__proxy__H__
#define __sdbuscpp__perftests_proxy_h__proxy__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
@ -16,13 +16,13 @@ namespace sdbuscpp {
class perftests_proxy
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.perftests";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.perftests";
protected:
perftests_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
proxy_.uponSignal("dataSignal").onInterface(interfaceName).call([this](const std::string& data){ this->onDataSignal(data); });
proxy_.uponSignal("dataSignal").onInterface(INTERFACE_NAME).call([this](const std::string& data){ this->onDataSignal(data); });
}
virtual void onDataSignal(const std::string& data) = 0;
@ -30,13 +30,13 @@ protected:
public:
void sendDataSignals(const uint32_t& numberOfSignals, const uint32_t& signalMsgSize)
{
proxy_.callMethod("sendDataSignals").onInterface(interfaceName).withArguments(numberOfSignals, signalMsgSize);
proxy_.callMethod("sendDataSignals").onInterface(INTERFACE_NAME).withArguments(numberOfSignals, signalMsgSize);
}
std::string concatenateTwoStrings(const std::string& string1, const std::string& string2)
{
std::string result;
proxy_.callMethod("concatenateTwoStrings").onInterface(interfaceName).withArguments(string1, string2).storeResultsTo(result);
proxy_.callMethod("concatenateTwoStrings").onInterface(INTERFACE_NAME).withArguments(string1, string2).storeResultsTo(result);
return result;
}

View File

@ -18,13 +18,13 @@ namespace celsius {
class thermometer_adaptor
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.stresstests.celsius.thermometer";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.celsius.thermometer";
protected:
thermometer_adaptor(sdbus::IObject& object)
: object_(object)
{
object_.registerMethod("getCurrentTemperature").onInterface(interfaceName).implementedAs([this](){ return this->getCurrentTemperature(); });
object_.registerMethod("getCurrentTemperature").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getCurrentTemperature(); });
}
private:

View File

@ -18,7 +18,7 @@ namespace celsius {
class thermometer_proxy
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.stresstests.celsius.thermometer";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.celsius.thermometer";
protected:
thermometer_proxy(sdbus::IProxy& proxy)
@ -30,7 +30,7 @@ public:
uint32_t getCurrentTemperature()
{
uint32_t result;
proxy_.callMethod("getCurrentTemperature").onInterface(interfaceName).storeResultsTo(result);
proxy_.callMethod("getCurrentTemperature").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}

View File

@ -17,20 +17,20 @@ namespace stresstests {
class concatenator_adaptor
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.stresstests.concatenator";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.concatenator";
protected:
concatenator_adaptor(sdbus::IObject& object)
: object_(object)
{
object_.registerMethod("concatenate").onInterface(interfaceName).implementedAs([this](sdbus::Result<std::string>&& result, std::map<std::string, sdbus::Variant> params){ this->concatenate(std::move(result), std::move(params)); });
object_.registerSignal("concatenatedSignal").onInterface(interfaceName).withParameters<std::string>();
object_.registerMethod("concatenate").onInterface(INTERFACE_NAME).implementedAs([this](sdbus::Result<std::string>&& result, std::map<std::string, sdbus::Variant> params){ this->concatenate(std::move(result), std::move(params)); });
object_.registerSignal("concatenatedSignal").onInterface(INTERFACE_NAME).withParameters<std::string>();
}
public:
void concatenatedSignal(const std::string& concatenatedString)
{
object_.emitSignal("concatenatedSignal").onInterface(interfaceName).withArguments(concatenatedString);
object_.emitSignal("concatenatedSignal").onInterface(INTERFACE_NAME).withArguments(concatenatedString);
}
private:

View File

@ -17,13 +17,13 @@ namespace stresstests {
class concatenator_proxy
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.stresstests.concatenator";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.concatenator";
protected:
concatenator_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
proxy_.uponSignal("concatenatedSignal").onInterface(interfaceName).call([this](const std::string& concatenatedString){ this->onConcatenatedSignal(concatenatedString); });
proxy_.uponSignal("concatenatedSignal").onInterface(INTERFACE_NAME).call([this](const std::string& concatenatedString){ this->onConcatenatedSignal(concatenatedString); });
}
virtual void onConcatenatedSignal(const std::string& concatenatedString) = 0;
@ -33,7 +33,7 @@ protected:
public:
void concatenate(const std::map<std::string, sdbus::Variant>& params)
{
proxy_.callMethodAsync("concatenate").onInterface(interfaceName).withArguments(params).uponReplyInvoke([this](const sdbus::Error* error, const std::string& result){ this->onConcatenateReply(result, error); });
proxy_.callMethodAsync("concatenate").onInterface(INTERFACE_NAME).withArguments(params).uponReplyInvoke([this](const sdbus::Error* error, const std::string& result){ this->onConcatenateReply(result, error); });
}
private:

View File

@ -18,13 +18,13 @@ namespace fahrenheit {
class thermometer_adaptor
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.stresstests.fahrenheit.thermometer";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer";
protected:
thermometer_adaptor(sdbus::IObject& object)
: object_(object)
{
object_.registerMethod("getCurrentTemperature").onInterface(interfaceName).implementedAs([this](){ return this->getCurrentTemperature(); });
object_.registerMethod("getCurrentTemperature").onInterface(INTERFACE_NAME).implementedAs([this](){ return this->getCurrentTemperature(); });
}
private:
@ -45,14 +45,14 @@ namespace thermometer {
class factory_adaptor
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.stresstests.fahrenheit.thermometer.factory";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer.factory";
protected:
factory_adaptor(sdbus::IObject& object)
: object_(object)
{
object_.registerMethod("createDelegateObject").onInterface(interfaceName).implementedAs([this](sdbus::Result<sdbus::ObjectPath>&& result){ this->createDelegateObject(std::move(result)); });
object_.registerMethod("destroyDelegateObject").onInterface(interfaceName).implementedAs([this](sdbus::Result<>&& result, sdbus::ObjectPath delegate){ this->destroyDelegateObject(std::move(result), std::move(delegate)); }).withNoReply();
object_.registerMethod("createDelegateObject").onInterface(INTERFACE_NAME).implementedAs([this](sdbus::Result<sdbus::ObjectPath>&& result){ this->createDelegateObject(std::move(result)); });
object_.registerMethod("destroyDelegateObject").onInterface(INTERFACE_NAME).implementedAs([this](sdbus::Result<>&& result, sdbus::ObjectPath delegate){ this->destroyDelegateObject(std::move(result), std::move(delegate)); }).withNoReply();
}
private:

View File

@ -18,7 +18,7 @@ namespace fahrenheit {
class thermometer_proxy
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.stresstests.fahrenheit.thermometer";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer";
protected:
thermometer_proxy(sdbus::IProxy& proxy)
@ -30,7 +30,7 @@ public:
uint32_t getCurrentTemperature()
{
uint32_t result;
proxy_.callMethod("getCurrentTemperature").onInterface(interfaceName).storeResultsTo(result);
proxy_.callMethod("getCurrentTemperature").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
@ -49,7 +49,7 @@ namespace thermometer {
class factory_proxy
{
public:
static constexpr const char* interfaceName = "org.sdbuscpp.stresstests.fahrenheit.thermometer.factory";
static constexpr const char* INTERFACE_NAME = "org.sdbuscpp.stresstests.fahrenheit.thermometer.factory";
protected:
factory_proxy(sdbus::IProxy& proxy)
@ -61,13 +61,13 @@ public:
sdbus::ObjectPath createDelegateObject()
{
sdbus::ObjectPath result;
proxy_.callMethod("createDelegateObject").onInterface(interfaceName).storeResultsTo(result);
proxy_.callMethod("createDelegateObject").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
void destroyDelegateObject(const sdbus::ObjectPath& delegate)
{
proxy_.callMethod("destroyDelegateObject").onInterface(interfaceName).withArguments(delegate).dontExpectReply();
proxy_.callMethod("destroyDelegateObject").onInterface(INTERFACE_NAME).withArguments(delegate).dontExpectReply();
}
private:

View File

@ -51,6 +51,7 @@ public:
MOCK_METHOD3(sd_bus_request_name, int(sd_bus *bus, const char *name, uint64_t flags));
MOCK_METHOD2(sd_bus_release_name, int(sd_bus *bus, const char *name));
MOCK_METHOD6(sd_bus_add_object_vtable, int(sd_bus *bus, sd_bus_slot **slot, const char *path, const char *interface, const sd_bus_vtable *vtable, void *userdata));
MOCK_METHOD3(sd_bus_add_object_manager, int(sd_bus *bus, sd_bus_slot **slot, const char *path));
MOCK_METHOD5(sd_bus_add_match, int(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata));
MOCK_METHOD1(sd_bus_slot_unref, sd_bus_slot*(sd_bus_slot *slot));

View File

@ -80,7 +80,7 @@ std::string AdaptorGenerator::processInterface(Node& interface) const
body << "class " << className << endl
<< "{" << endl
<< "public:" << endl
<< tab << "static constexpr const char* interfaceName = \"" << ifaceName << "\";" << endl << endl
<< tab << "static constexpr const char* INTERFACE_NAME = \"" << ifaceName << "\";" << endl << endl
<< "protected:" << endl
<< tab << className << "(sdbus::IObject& object)" << endl
<< tab << tab << ": object_(object)" << endl;
@ -109,7 +109,7 @@ std::string AdaptorGenerator::processInterface(Node& interface) const
if(!annotationRegistration.empty())
{
std::stringstream str;
str << tab << tab << "object_.setInterfaceFlags(interfaceName)" << annotationRegistration << ";" << endl;
str << tab << tab << "object_.setInterfaceFlags(INTERFACE_NAME)" << annotationRegistration << ";" << endl;
annotationRegistration = str.str();
}
@ -207,7 +207,7 @@ std::tuple<std::string, std::string> AdaptorGenerator::processMethods(const Node
registrationSS << tab << tab << "object_.registerMethod(\""
<< methodName << "\")"
<< ".onInterface(interfaceName)"
<< ".onInterface(INTERFACE_NAME)"
<< ".implementedAs("
<< "[this]("
<< (async ? "sdbus::Result<" + outArgsToType(outArgs, true) + ">&& result" + (argTypeStr.empty() ? "" : ", ") : "")
@ -260,7 +260,7 @@ std::tuple<std::string, std::string> AdaptorGenerator::processSignals(const Node
signalRegistrationSS << tab << tab
<< "object_.registerSignal(\"" << name << "\")"
".onInterface(interfaceName)";
".onInterface(INTERFACE_NAME)";
if (args.size() > 0)
{
@ -273,7 +273,7 @@ std::tuple<std::string, std::string> AdaptorGenerator::processSignals(const Node
signalMethodSS << tab << "void " << name << "(" << argTypeStr << ")" << endl
<< tab << "{" << endl
<< tab << tab << "object_.emitSignal(\"" << name << "\")"
".onInterface(interfaceName)";
".onInterface(INTERFACE_NAME)";
if (!argStr.empty())
{
@ -322,7 +322,7 @@ std::tuple<std::string, std::string> AdaptorGenerator::processProperties(const N
registrationSS << tab << tab << "object_.registerProperty(\""
<< propertyName << "\")"
<< ".onInterface(interfaceName)";
<< ".onInterface(INTERFACE_NAME)";
if (propertyAccess == "read" || propertyAccess == "readwrite")
{

View File

@ -80,7 +80,7 @@ std::string ProxyGenerator::processInterface(Node& interface) const
body << "class " << className << endl
<< "{" << endl
<< "public:" << endl
<< tab << "static constexpr const char* interfaceName = \"" << ifaceName << "\";" << endl << endl
<< tab << "static constexpr const char* INTERFACE_NAME = \"" << ifaceName << "\";" << endl << endl
<< "protected:" << endl
<< tab << className << "(sdbus::IProxy& proxy)" << endl
<< tab << tab << ": proxy_(proxy)" << endl;
@ -169,7 +169,7 @@ std::tuple<std::string, std::string> ProxyGenerator::processMethods(const Nodes&
}
definitionSS << tab << tab << "proxy_.callMethod" << (async ? "Async" : "") << "(\"" << name << "\")"
".onInterface(interfaceName)";
".onInterface(INTERFACE_NAME)";
if (inArgs.size() > 0)
{
@ -220,7 +220,7 @@ std::tuple<std::string, std::string> ProxyGenerator::processSignals(const Nodes&
registrationSS << tab << tab << "proxy_"
".uponSignal(\"" << name << "\")"
".onInterface(interfaceName)"
".onInterface(INTERFACE_NAME)"
".call([this](" << argTypeStr << ")"
"{ this->on" << nameBigFirst << "(" << argStr << "); });" << endl;
@ -248,7 +248,7 @@ std::string ProxyGenerator::processProperties(const Nodes& properties) const
propertySS << tab << propertyType << " " << propertyName << "()" << endl
<< tab << "{" << endl;
propertySS << tab << tab << "return proxy_.getProperty(\"" << propertyName << "\")"
".onInterface(interfaceName)";
".onInterface(INTERFACE_NAME)";
propertySS << ";" << endl << tab << "}" << endl << endl;
}
@ -257,7 +257,7 @@ std::string ProxyGenerator::processProperties(const Nodes& properties) const
propertySS << tab << "void " << propertyName << "(" << propertyTypeArg << ")" << endl
<< tab << "{" << endl;
propertySS << tab << tab << "proxy_.setProperty(\"" << propertyName << "\")"
".onInterface(interfaceName)"
".onInterface(INTERFACE_NAME)"
".toValue(" << propertyArg << ")";
propertySS << ";" << endl << tab << "}" << endl << endl;
}