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
+22 -23
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)
+13 -12
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);
+15 -12
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;
};
}
+16 -4
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)
+6 -1
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_;
};
}
+5 -7
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 );
}
}
}
+2 -6
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_;
};