mirror of
https://github.com/Kistler-Group/sdbus-cpp.git
synced 2025-06-25 01:21:34 +02:00
Compare commits
24 Commits
v1.1.0
...
fix_deprec
Author | SHA1 | Date | |
---|---|---|---|
e199dc58cf | |||
ad7731d900 | |||
101dd1c2ba | |||
299e6940cd | |||
3f825ffb30 | |||
35bffd0f25 | |||
e33a890ce7 | |||
751c1addc4 | |||
2991fa4960 | |||
0f2362d8c3 | |||
e07c1f3981 | |||
58426966f4 | |||
4e105081c9 | |||
5ec6027d5f | |||
d864e1dfa4 | |||
b7f3d7c876 | |||
2a4c241303 | |||
5e933c3f17 | |||
b5aee6d019 | |||
5caea3b72b | |||
b7a9c63ff0 | |||
7f437a6e06 | |||
f492472e9f | |||
f673e57a47 |
@ -4,7 +4,7 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
project(sdbus-c++ VERSION 1.1.0 LANGUAGES C CXX)
|
||||
project(sdbus-c++ VERSION 1.2.0 LANGUAGES C CXX)
|
||||
|
||||
include(GNUInstallDirs) # Installation directories for `install` command and pkgconfig file
|
||||
|
||||
@ -58,6 +58,7 @@ set(SDBUSCPP_HDR_SRCS
|
||||
${SDBUSCPP_SOURCE_DIR}/Connection.h
|
||||
${SDBUSCPP_SOURCE_DIR}/IConnection.h
|
||||
${SDBUSCPP_SOURCE_DIR}/MessageUtils.h
|
||||
${SDBUSCPP_SOURCE_DIR}/Utils.h
|
||||
${SDBUSCPP_SOURCE_DIR}/Object.h
|
||||
${SDBUSCPP_SOURCE_DIR}/Proxy.h
|
||||
${SDBUSCPP_SOURCE_DIR}/ScopeGuard.h
|
||||
@ -80,6 +81,7 @@ set(SDBUSCPP_PUBLIC_HDRS
|
||||
${SDBUSCPP_INCLUDE_DIR}/Types.h
|
||||
${SDBUSCPP_INCLUDE_DIR}/TypeTraits.h
|
||||
${SDBUSCPP_INCLUDE_DIR}/Flags.h
|
||||
${SDBUSCPP_INCLUDE_DIR}/SdbusAsio.h
|
||||
${SDBUSCPP_INCLUDE_DIR}/sdbus-c++.h)
|
||||
|
||||
set(SDBUSCPP_SRCS ${SDBUSCPP_CPP_SRCS} ${SDBUSCPP_HDR_SRCS} ${SDBUSCPP_PUBLIC_HDRS})
|
||||
@ -209,6 +211,11 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/sdbus-c++-config.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/sdbus-c++
|
||||
COMPONENT dev)
|
||||
|
||||
if(BUILD_SHARED_LIBS AND (BUILD_LIBSYSTEMD OR Systemd_LINK_LIBRARIES MATCHES "/libsystemd\.a(;|$)"))
|
||||
set(PKGCONFIG_REQS ".private")
|
||||
else()
|
||||
set(PKGCONFIG_REQS "")
|
||||
endif()
|
||||
configure_file(pkgconfig/sdbus-c++.pc.in pkgconfig/sdbus-c++.pc @ONLY)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/sdbus-c++.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT dev)
|
||||
|
15
ChangeLog
15
ChangeLog
@ -201,3 +201,18 @@ v1.1.0
|
||||
- Add support for unregistering signal handler
|
||||
- Add support for chrono literals in sdbus-c++-xml2cpp generator
|
||||
- Additional little fixes and improvements in code, build system, and documentation
|
||||
|
||||
v1.2.0
|
||||
- Add support for match rules
|
||||
- Add support for session bus connection at custom address
|
||||
- Add CMake variable for extra libsystemd config options
|
||||
- Use pseudo D-Bus connection for plain messages
|
||||
- Rename dont_request_slot tag to floating_slot
|
||||
- Add validity checks for names and paths
|
||||
- Remove executable flag from source files
|
||||
- Detect missing type after array declaration
|
||||
- Fix invalid assert on event fd
|
||||
- Enable move for ObjectPath and Signature
|
||||
- Add printer for std::chrono in googletest v1.11.0
|
||||
- Fix potential undefined behavior in creation of sdbus::Error
|
||||
- Additional little fixes and improvements in code, build system, and documentation
|
||||
|
@ -62,6 +62,10 @@ $ sudo cmake --build . --target install
|
||||
|
||||
Defines version of systemd to be downloaded, built and integrated into sdbus-c++. Default value: `242`.
|
||||
|
||||
* `LIBSYSTEMD_EXTRA_CONFIG_OPTS` [string]
|
||||
|
||||
Additional options to be passed as-is to the libsystemd build system (meson for systemd v242) in its configure step. Can be used for passing e.g. toolchain file path in case of cross builds. Default value: empty.
|
||||
|
||||
* `CMAKE_BUILD_TYPE` [string]
|
||||
|
||||
This is a CMake-builtin option. Set to `Release` to build sdbus-c++ for production use. Set to `Debug` if you want to help further develop (and debug) the library :)
|
||||
|
@ -6,6 +6,10 @@ if((NOT MESON) OR (NOT NINJA))
|
||||
message(FATAL_ERROR "Meson and Ninja are required to build libsystemd")
|
||||
endif()
|
||||
|
||||
if(NOT GPERF)
|
||||
message(WARNING "gperf was not found, libsystemd configuration may fail")
|
||||
endif()
|
||||
|
||||
find_library(GLIBC_RT_LIBRARY rt)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(MOUNT mount)
|
||||
@ -15,6 +19,7 @@ if (NOT CAP_FOUND)
|
||||
endif()
|
||||
|
||||
set(LIBSYSTEMD_VERSION "242" CACHE STRING "libsystemd version (>=239) to build and incorporate into libsdbus-c++")
|
||||
set(LIBSYSTEMD_EXTRA_CONFIG_OPTS "" CACHE STRING "Additional configuration options to be passed as-is to libsystemd build system")
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(LIBSYSTEMD_BUILD_TYPE "plain")
|
||||
@ -41,7 +46,7 @@ ExternalProject_Add(LibsystemdBuildProject
|
||||
GIT_SHALLOW 1
|
||||
UPDATE_COMMAND ""
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E remove <BINARY_DIR>/*
|
||||
COMMAND ${MESON} --prefix=<INSTALL_DIR> --buildtype=${LIBSYSTEMD_BUILD_TYPE} -Dstatic-libsystemd=pic -Dselinux=false <SOURCE_DIR> <BINARY_DIR>
|
||||
COMMAND ${MESON} --prefix=<INSTALL_DIR> --buildtype=${LIBSYSTEMD_BUILD_TYPE} -Dstatic-libsystemd=pic -Dselinux=false <SOURCE_DIR> <BINARY_DIR> ${LIBSYSTEMD_EXTRA_CONFIG_OPTS}
|
||||
BUILD_COMMAND ${BUILD_VERSION_H}
|
||||
COMMAND ${NINJA} -C <BINARY_DIR> libsystemd.a
|
||||
BUILD_ALWAYS 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
Systemd and dbus configuration
|
||||
Systemd and D-Bus configuration
|
||||
=======================
|
||||
|
||||
**Table of contents**
|
||||
@ -10,15 +10,13 @@ Systemd and dbus configuration
|
||||
Introduction
|
||||
------------
|
||||
|
||||
To run executable as a systemd service you may need some additional setup. For example, you may need explicitly allow
|
||||
the usage of your service. Following chapters contain template configurations.
|
||||
To run executable as a systemd service you may need some additional setup. For example, you may need explicitly allow the usage of your service. Following chapters contain template configurations.
|
||||
|
||||
|
||||
Systemd configuration
|
||||
---------------------------------------
|
||||
|
||||
Filename should use `.service` extension. It also must be placed in configuration directory (/etc/systemd/system in
|
||||
Ubuntu 18.04.1 LTS)
|
||||
Filename should use `.service` extension. It also must be placed in configuration directory (/etc/systemd/system in Ubuntu 18.04.1 LTS)
|
||||
|
||||
```
|
||||
[Unit]
|
||||
@ -31,12 +29,10 @@ ExecStart=/path/to/executable
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Dbus configuration
|
||||
D-Bus configuration
|
||||
------------------
|
||||
|
||||
Typical default D-Bus configuration does not allow to register services except explicitly allowed. Filename should
|
||||
contain name of your service, e.g `/etc/dbus-1/system.d/org.sdbuscpp.concatenator.conf`. So, here is template
|
||||
configuration to use dbus interface under root:
|
||||
Typical default D-Bus configuration does not allow to register services except explicitly allowed. To allow a service to register its D-Bus API, we must place an appropriate conf file in `/etc/dbus-1/system.d/` directory. The conf file name must be `<service-name>.conf`. I.e., full file path for Concatenator example from sdbus-c++ tutorial would be `/etc/dbus-1/system.d/org.sdbuscpp.concatenator.conf`. And here is template configuration to use its D-Bus interface under root:
|
||||
|
||||
```
|
||||
<!DOCTYPE busconfig PUBLIC
|
||||
@ -45,10 +41,10 @@ configuration to use dbus interface under root:
|
||||
<busconfig>
|
||||
<policy user="root">
|
||||
<allow own="org.sdbuscpp.concatenator"/>
|
||||
<allow send_destination="org.sdbuscpp"/>
|
||||
<allow send_destination="org.sdbuscpp.concatenator"/>
|
||||
<allow send_interface="org.sdbuscpp.concatenator"/>
|
||||
</policy>
|
||||
</busconfig>
|
||||
```
|
||||
|
||||
If you need access from other user `root` should be substituted by desired username. For more refer to `man dbus-daemon`.
|
||||
If you need access from other user then `root` should be substituted by desired username. Or you can simply use policy `<policy context="default">` like [conf file](/tests/integrationtests/files/org.sdbuscpp.integrationtests.conf) for sdbus-c++ integration tests is doing it. For more information refer to `man dbus-daemon`.
|
||||
|
@ -19,7 +19,8 @@ Using sdbus-c++ library
|
||||
14. [Asynchronous client-side methods](#asynchronous-client-side-methods)
|
||||
15. [Using D-Bus properties](#using-d-bus-properties)
|
||||
16. [Standard D-Bus interfaces](#standard-d-bus-interfaces)
|
||||
17. [Conclusion](#conclusion)
|
||||
17. [Support for match rules](#support-for-match-rules)
|
||||
18. [Conclusion](#conclusion)
|
||||
|
||||
Introduction
|
||||
------------
|
||||
@ -118,6 +119,10 @@ There are Yocto recipes for sdbus-c++ available in the [`meta-oe`](https://githu
|
||||
|
||||
sdbus-c++ recipe is available in ConanCenter repository as [`sdbus-cpp`](https://conan.io/center/sdbus-cpp).
|
||||
|
||||
### Buildroot
|
||||
|
||||
There is the Buildroot package [`sdbus-cpp`](https://git.buildroot.net/buildroot/tree/package/sdbus-cpp?h=2022.02) to build sdbus-c++ library itself without a code generation tool.
|
||||
|
||||
Contributors willing to help with bringing sdbus-c++ to other popular package systems are welcome.
|
||||
|
||||
Verifying sdbus-c++
|
||||
@ -221,7 +226,7 @@ Let's have an object `/org/sdbuscpp/concatenator` that implements the `org.sdbus
|
||||
|
||||
In the following sections, we will elaborate on the ways of implementing such an object on both the server and the client side.
|
||||
|
||||
> **_Note_:** In order to be able to call methods of your system bus-based D-Bus service, a D-Bus security policy file has to be put in place for that service. See [dbus-daemon documentation](https://dbus.freedesktop.org/doc/dbus-daemon.1.html), sections *INTEGRATING SYSTEM SERVICES* and *CONFIGURATION FILE*. As an example, you may look at the [policy file for sdbus-c++ integration tests](/tests/integrationtests/files/org.sdbuscpp.integrationtests.conf).
|
||||
> **Before running Concatenator example in your system:** In order for your service to be allowed to provide a D-Bus API on system bus, a D-Bus security policy file has to be put in place for that service. Otherwise the service will fail to start (you'll get `[org.freedesktop.DBus.Error.AccessDenied] Failed to request bus name (Permission denied)`, for example). To make the Concatenator example work in your system, [look in this section of systemd configuration](systemd-dbus-config.md#dbus-configuration) for how to name the file, where to place it, how to populate it. For further information, consult [dbus-daemon documentation](https://dbus.freedesktop.org/doc/dbus-daemon.1.html), sections *INTEGRATING SYSTEM SERVICES* and *CONFIGURATION FILE*. As an example used for sdbus-c++ integration tests, you may look at the [policy file for sdbus-c++ integration tests](/tests/integrationtests/files/org.sdbuscpp.integrationtests.conf).
|
||||
|
||||
Implementing the Concatenator example using basic sdbus-c++ API layer
|
||||
---------------------------------------------------------------------
|
||||
@ -1275,6 +1280,11 @@ Note that signals of afore-mentioned standard D-Bus interfaces are not emitted b
|
||||
|
||||
Working examples of using standard D-Bus interfaces can be found in [sdbus-c++ integration tests](/tests/integrationtests/DBusStandardInterfacesTests.cpp) or the [examples](/examples) directory.
|
||||
|
||||
Support for match rules
|
||||
-----------------------
|
||||
|
||||
`IConnection` class provides `addMatch` method that you can use to install match rules. An associated callback handler will be called upon an incoming message matching given match rule. There is support for both client-owned and floating (library-owned) match rules. Consult `IConnection` header or sdbus-c++ doxygen documentation for more information.
|
||||
|
||||
Conclusion
|
||||
----------
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file AdaptorInterfaces.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file ConvenienceApiClasses.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file ConvenienceApiClasses.inl
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Error.h
|
||||
*
|
||||
@ -43,6 +43,11 @@ namespace sdbus {
|
||||
: public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit Error(const std::string& name, const char* message = nullptr)
|
||||
: Error(name, std::string(message ? message : ""))
|
||||
{
|
||||
}
|
||||
|
||||
Error(const std::string& name, const std::string& message)
|
||||
: std::runtime_error("[" + name + "] " + message)
|
||||
, name_(name)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Flags.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file IConnection.h
|
||||
*
|
||||
@ -27,6 +27,7 @@
|
||||
#ifndef SDBUS_CXX_ICONNECTION_H_
|
||||
#define SDBUS_CXX_ICONNECTION_H_
|
||||
|
||||
#include <sdbus-c++/TypeTraits.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
@ -77,6 +78,11 @@ namespace sdbus {
|
||||
*/
|
||||
uint64_t timeout_usec;
|
||||
|
||||
/*!
|
||||
* The read fd to be monitored by the event loop.
|
||||
*/
|
||||
int event_fd;
|
||||
|
||||
/*!
|
||||
* Get the event poll timeout.
|
||||
*
|
||||
@ -166,9 +172,15 @@ namespace sdbus {
|
||||
* the connection. This is a convenient way to interrogate a connection
|
||||
* to see what objects it has.
|
||||
*
|
||||
* This call creates a floating registration. The ObjectManager will
|
||||
* be there for the object path until the connection is destroyed.
|
||||
*
|
||||
* Another, recommended way to add object managers is directly through
|
||||
* IObject API.
|
||||
*
|
||||
* @throws sdbus::Error in case of failure
|
||||
*/
|
||||
virtual void addObjectManager(const std::string& objectPath) = 0;
|
||||
[[deprecated("Use one of other addObjectManager overloads")]] virtual void addObjectManager(const std::string& objectPath) = 0;
|
||||
|
||||
/*!
|
||||
* @brief Returns fd, I/O events and timeout data you can pass to poll
|
||||
@ -241,6 +253,64 @@ namespace sdbus {
|
||||
*/
|
||||
virtual uint64_t getMethodCallTimeout() const = 0;
|
||||
|
||||
/*!
|
||||
* @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
|
||||
* to see what objects it has.
|
||||
*
|
||||
* This call creates a floating registration. The ObjectManager will
|
||||
* be there for the object path until the connection is destroyed.
|
||||
*
|
||||
* Another, recommended way to add object managers is directly through
|
||||
* IObject API.
|
||||
*
|
||||
* @throws sdbus::Error in case of failure
|
||||
*/
|
||||
virtual void addObjectManager(const std::string& objectPath, floating_slot_t) = 0;
|
||||
|
||||
/*!
|
||||
* @brief Adds a match rule for incoming message dispatching
|
||||
*
|
||||
* @param[in] match Match expression to filter incoming D-Bus message
|
||||
* @param[in] callback Callback handler to be called upon incoming D-Bus message matching the rule
|
||||
* @return RAII-style slot handle representing the ownership of the subscription
|
||||
*
|
||||
* The method installs a match rule for messages received on the specified bus connection.
|
||||
* The syntax of the match rule expression passed in match is described in the D-Bus specification.
|
||||
* The specified handler function callback is called for each incoming message matching the specified
|
||||
* expression. The match is installed synchronously when connected to a bus broker, i.e. the call
|
||||
* sends a control message requested the match to be added to the broker and waits until the broker
|
||||
* confirms the match has been installed successfully.
|
||||
*
|
||||
* Simply let go of the slot instance to uninstall the match rule from the bus connection. The slot
|
||||
* must not outlive the connection for the slot is associated with it.
|
||||
*
|
||||
* For more information, consult `man sd_bus_add_match`.
|
||||
*
|
||||
* @throws sdbus::Error in case of failure
|
||||
*/
|
||||
[[nodiscard]] virtual Slot addMatch(const std::string& match, message_handler callback) = 0;
|
||||
|
||||
/*!
|
||||
* @brief Adds a floating match rule for incoming message dispatching
|
||||
*
|
||||
* @param[in] match Match expression to filter incoming D-Bus message
|
||||
* @param[in] callback Callback handler to be called upon incoming D-Bus message matching the rule
|
||||
* @param[in] Floating slot tag
|
||||
*
|
||||
* The method installs a floating match rule for messages received on the specified bus connection.
|
||||
* Floating means that the bus connection object owns the match rule, i.e. lifetime of the match rule
|
||||
* is bound to the lifetime of the bus connection.
|
||||
*
|
||||
* Refer to the @c addMatch(const std::string& match, message_handler callback) documentation for more
|
||||
* information.
|
||||
*
|
||||
* @throws sdbus::Error in case of failure
|
||||
*/
|
||||
virtual void addMatch(const std::string& match, message_handler callback, floating_slot_t) = 0;
|
||||
|
||||
/*!
|
||||
* @copydoc IConnection::enterEventLoop()
|
||||
*
|
||||
@ -298,7 +368,7 @@ namespace sdbus {
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Creates/opens D-Bus system connection
|
||||
* @brief Creates/opens D-Bus system bus connection
|
||||
*
|
||||
* @return Connection instance
|
||||
*
|
||||
@ -307,7 +377,7 @@ namespace sdbus {
|
||||
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createConnection();
|
||||
|
||||
/*!
|
||||
* @brief Creates/opens D-Bus system connection with a name
|
||||
* @brief Creates/opens D-Bus system bus connection with a name
|
||||
*
|
||||
* @param[in] name Name to request on the connection after its opening
|
||||
* @return Connection instance
|
||||
@ -317,8 +387,7 @@ namespace sdbus {
|
||||
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createConnection(const std::string& name);
|
||||
|
||||
/*!
|
||||
* @brief Creates/opens D-Bus user connection when in a user context,
|
||||
* and a system connection, otherwise.
|
||||
* @brief Creates/opens D-Bus session bus connection when in a user context, and a system bus connection, otherwise.
|
||||
*
|
||||
* @return Connection instance
|
||||
*
|
||||
@ -327,8 +396,7 @@ namespace sdbus {
|
||||
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createDefaultBusConnection();
|
||||
|
||||
/*!
|
||||
* @brief Creates/opens D-Bus user connection with a name when in a user
|
||||
* context, and a system connection with a name, otherwise.
|
||||
* @brief Creates/opens D-Bus session bus connection with a name when in a user context, and a system bus connection with a name, otherwise.
|
||||
*
|
||||
* @param[in] name Name to request on the connection after its opening
|
||||
* @return Connection instance
|
||||
@ -338,7 +406,7 @@ namespace sdbus {
|
||||
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createDefaultBusConnection(const std::string& name);
|
||||
|
||||
/*!
|
||||
* @brief Creates/opens D-Bus system connection
|
||||
* @brief Creates/opens D-Bus system bus connection
|
||||
*
|
||||
* @return Connection instance
|
||||
*
|
||||
@ -347,7 +415,7 @@ namespace sdbus {
|
||||
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSystemBusConnection();
|
||||
|
||||
/*!
|
||||
* @brief Creates/opens D-Bus system connection with a name
|
||||
* @brief Creates/opens D-Bus system bus connection with a name
|
||||
*
|
||||
* @param[in] name Name to request on the connection after its opening
|
||||
* @return Connection instance
|
||||
@ -357,7 +425,7 @@ namespace sdbus {
|
||||
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const std::string& name);
|
||||
|
||||
/*!
|
||||
* @brief Creates/opens D-Bus session connection
|
||||
* @brief Creates/opens D-Bus session bus connection
|
||||
*
|
||||
* @return Connection instance
|
||||
*
|
||||
@ -366,7 +434,7 @@ namespace sdbus {
|
||||
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSessionBusConnection();
|
||||
|
||||
/*!
|
||||
* @brief Creates/opens D-Bus session connection with a name
|
||||
* @brief Creates/opens D-Bus session bus connection with a name
|
||||
*
|
||||
* @param[in] name Name to request on the connection after its opening
|
||||
* @return Connection instance
|
||||
@ -375,6 +443,18 @@ namespace sdbus {
|
||||
*/
|
||||
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const std::string& name);
|
||||
|
||||
/*!
|
||||
* @brief Creates/opens D-Bus session bus connection at a custom address
|
||||
*
|
||||
* @param[in] address ";"-separated list of addresses of bus brokers to try to connect
|
||||
* @return Connection instance
|
||||
*
|
||||
* @throws sdbus::Error in case of failure
|
||||
*
|
||||
* Consult manual pages for `sd_bus_set_address` of the underlying sd-bus library for more information.
|
||||
*/
|
||||
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSessionBusConnectionWithAddress(const std::string& address);
|
||||
|
||||
/*!
|
||||
* @brief Creates/opens D-Bus system connection on a remote host using ssh
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file IObject.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file IProxy.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Message.h
|
||||
*
|
||||
@ -32,7 +32,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
@ -55,16 +54,11 @@ namespace sdbus {
|
||||
|
||||
namespace sdbus {
|
||||
|
||||
// Assume the caller has already obtained message ownership
|
||||
struct adopt_message_t { explicit adopt_message_t() = default; };
|
||||
inline constexpr adopt_message_t adopt_message{};
|
||||
|
||||
/********************************************//**
|
||||
* @class Message
|
||||
*
|
||||
* Message represents a D-Bus message, which can be either method call message,
|
||||
* method reply message, signal message, or a plain message serving as a storage
|
||||
* for serialized data.
|
||||
* method reply message, signal message, or a plain message.
|
||||
*
|
||||
* Serialization and deserialization functions are provided for types supported
|
||||
* by D-Bus.
|
||||
@ -173,21 +167,17 @@ namespace sdbus {
|
||||
mutable bool ok_{true};
|
||||
};
|
||||
|
||||
struct dont_request_slot_t { explicit dont_request_slot_t() = default; };
|
||||
inline constexpr dont_request_slot_t dont_request_slot{};
|
||||
|
||||
class MethodCall : public Message
|
||||
{
|
||||
using Message::Message;
|
||||
friend Factory;
|
||||
|
||||
public:
|
||||
using Slot = std::unique_ptr<void, std::function<void(void*)>>;
|
||||
|
||||
MethodCall() = default;
|
||||
|
||||
MethodReply send(uint64_t timeout) const;
|
||||
void send(void* callback, void* userData, uint64_t timeout, dont_request_slot_t) const;
|
||||
[[deprecated("Use send overload with floating_slot instead")]] void send(void* callback, void* userData, uint64_t timeout, dont_request_slot_t) const;
|
||||
void send(void* callback, void* userData, uint64_t timeout, floating_slot_t) const;
|
||||
[[nodiscard]] Slot send(void* callback, void* userData, uint64_t timeout) const;
|
||||
|
||||
MethodReply createReply() const;
|
||||
@ -244,6 +234,7 @@ namespace sdbus {
|
||||
PropertyGetReply() = default;
|
||||
};
|
||||
|
||||
// Represents any of the above message types, or just a message that serves as a container for data
|
||||
class PlainMessage : public Message
|
||||
{
|
||||
using Message::Message;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file MethodResult.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file ProxyInterfaces.h
|
||||
*
|
||||
|
67
include/sdbus-c++/SdbusAsio.h
Normal file
67
include/sdbus-c++/SdbusAsio.h
Normal file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <memory>
|
||||
#include <sdbus-c++/sdbus-c++.h>
|
||||
|
||||
class SdbusAsio final : boost::noncopyable {
|
||||
public:
|
||||
explicit SdbusAsio(boost::asio::io_context& io_context,
|
||||
std::unique_ptr<sdbus::IConnection> conn = sdbus::createDefaultBusConnection())
|
||||
: conn_ { std::move(conn) }
|
||||
, timer_ { io_context }
|
||||
, dbus_desc_ { io_context }
|
||||
, event_desc_ { io_context }
|
||||
|
||||
{
|
||||
auto poll_data = conn_->getEventLoopPollData();
|
||||
dbus_desc_.async_wait(boost::asio::posix::stream_descriptor::wait_read,
|
||||
[this](const boost::system::error_code&) { processRead(); });
|
||||
dbus_desc_.assign(poll_data.fd);
|
||||
|
||||
event_desc_.async_read_some(boost::asio::null_buffers(), [this](auto&, auto) { processEvent(); });
|
||||
event_desc_.assign(poll_data.event_fd);
|
||||
|
||||
if (poll_data.timeout_usec != UINT64_MAX) {
|
||||
timer_.async_wait([this](boost::system::error_code const&) { processTimeout(); });
|
||||
timer_.expires_after(boost::posix_time::microsec(poll_data.timeout_usec));
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<sdbus::IConnection> getConnection() { return conn_; }
|
||||
|
||||
private:
|
||||
void process()
|
||||
{
|
||||
for (auto i = 0; i < DBUS_PROCESS_MAX; i++) {
|
||||
if (!conn_->processPendingRequest()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void processRead()
|
||||
{
|
||||
process();
|
||||
dbus_desc_.async_wait(boost::asio::posix::stream_descriptor::wait_read,
|
||||
[this](const boost::system::error_code&) { processRead(); });
|
||||
}
|
||||
|
||||
void processEvent()
|
||||
{
|
||||
process();
|
||||
event_desc_.async_read_some(boost::asio::null_buffers(), [this](auto, auto) { processEvent(); });
|
||||
}
|
||||
|
||||
void processTimeout()
|
||||
{
|
||||
process();
|
||||
timer_.async_wait([this](boost::system::error_code const&) { processTimeout(); });
|
||||
}
|
||||
|
||||
static constexpr auto DBUS_PROCESS_MAX = 32;
|
||||
std::shared_ptr<sdbus::IConnection> conn_;
|
||||
boost::asio::deadline_timer timer_;
|
||||
boost::asio::posix::stream_descriptor dbus_desc_;
|
||||
boost::asio::posix::stream_descriptor event_desc_;
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file StandardInterfaces.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file TypeTraits.h
|
||||
*
|
||||
@ -33,6 +33,7 @@
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
// Forward declarations
|
||||
@ -45,6 +46,7 @@ namespace sdbus {
|
||||
class MethodCall;
|
||||
class MethodReply;
|
||||
class Signal;
|
||||
class Message;
|
||||
class PropertySetCall;
|
||||
class PropertyGetReply;
|
||||
template <typename... _Results> class Result;
|
||||
@ -53,12 +55,34 @@ namespace sdbus {
|
||||
|
||||
namespace sdbus {
|
||||
|
||||
// Callbacks from sdbus-c++
|
||||
using method_callback = std::function<void(MethodCall msg)>;
|
||||
using async_reply_handler = std::function<void(MethodReply& reply, const Error* error)>;
|
||||
using signal_handler = std::function<void(Signal& signal)>;
|
||||
using message_handler = std::function<void(Message& msg)>;
|
||||
using property_set_callback = std::function<void(PropertySetCall& msg)>;
|
||||
using property_get_callback = std::function<void(PropertyGetReply& reply)>;
|
||||
|
||||
// Type-erased RAII-style handle to callbacks/subscriptions registered to sdbus-c++
|
||||
using Slot = std::unique_ptr<void, std::function<void(void*)>>;
|
||||
|
||||
// Tag specifying that an owning slot handle shall be returned from the function
|
||||
struct request_slot_t { explicit request_slot_t() = default; };
|
||||
inline constexpr request_slot_t request_slot{};
|
||||
// Tag specifying that the library shall own the slot resulting from the call of the function (so-called floating slot)
|
||||
struct floating_slot_t { explicit floating_slot_t() = default; };
|
||||
inline constexpr floating_slot_t floating_slot{};
|
||||
// Deprecated name for the above -- a floating slot
|
||||
struct dont_request_slot_t { explicit dont_request_slot_t() = default; };
|
||||
[[deprecated("Replaced by floating_slot")]] inline constexpr dont_request_slot_t dont_request_slot{};
|
||||
// Tag denoting the assumption that the caller has already obtained message ownership
|
||||
struct adopt_message_t { explicit adopt_message_t() = default; };
|
||||
inline constexpr adopt_message_t adopt_message{};
|
||||
// Tag denoting the assumption that the caller has already obtained fd ownership
|
||||
struct adopt_fd_t { explicit adopt_fd_t() = default; };
|
||||
inline constexpr adopt_fd_t adopt_fd{};
|
||||
|
||||
// Template specializations for getting D-Bus signatures from C++ types
|
||||
template <typename _T>
|
||||
struct signature_of
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Types.h
|
||||
*
|
||||
@ -155,7 +155,9 @@ namespace sdbus {
|
||||
using std::string::string;
|
||||
ObjectPath() = default; // Fixes gcc 6.3 error (default c-tor is not imported in above using declaration)
|
||||
ObjectPath(const ObjectPath&) = default; // Fixes gcc 8.3 error (deleted copy constructor)
|
||||
ObjectPath(ObjectPath&&) = default; // Enable move - user-declared copy ctor prevents implicit creation
|
||||
ObjectPath& operator = (const ObjectPath&) = default; // Fixes gcc 8.3 error (deleted copy assignment)
|
||||
ObjectPath& operator = (ObjectPath&&) = default; // Enable move - user-declared copy assign prevents implicit creation
|
||||
ObjectPath(std::string path)
|
||||
: std::string(std::move(path))
|
||||
{}
|
||||
@ -174,16 +176,15 @@ namespace sdbus {
|
||||
using std::string::string;
|
||||
Signature() = default; // Fixes gcc 6.3 error (default c-tor is not imported in above using declaration)
|
||||
Signature(const Signature&) = default; // Fixes gcc 8.3 error (deleted copy constructor)
|
||||
Signature(Signature&&) = default; // Enable move - user-declared copy ctor prevents implicit creation
|
||||
Signature& operator = (const Signature&) = default; // Fixes gcc 8.3 error (deleted copy assignment)
|
||||
Signature& operator = (Signature&&) = default; // Enable move - user-declared copy assign prevents implicit creation
|
||||
Signature(std::string path)
|
||||
: std::string(std::move(path))
|
||||
{}
|
||||
using std::string::operator=;
|
||||
};
|
||||
|
||||
struct adopt_fd_t { explicit adopt_fd_t() = default; };
|
||||
inline constexpr adopt_fd_t adopt_fd{};
|
||||
|
||||
/********************************************//**
|
||||
* @struct UnixFd
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file sdbus-c++.h
|
||||
*
|
||||
|
@ -5,7 +5,7 @@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: C++ library on top of sd-bus, a systemd D-Bus library
|
||||
Requires: libsystemd
|
||||
Requires@PKGCONFIG_REQS@: libsystemd
|
||||
Version: @SDBUSCPP_VERSION@
|
||||
Libs: -L${libdir} -l@PROJECT_NAME@
|
||||
Cflags: -I${includedir}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Connection.cpp
|
||||
*
|
||||
@ -27,6 +27,7 @@
|
||||
#include "Connection.h"
|
||||
#include "SdBus.h"
|
||||
#include "MessageUtils.h"
|
||||
#include "Utils.h"
|
||||
#include <sdbus-c++/Message.h>
|
||||
#include <sdbus-c++/Error.h>
|
||||
#include "ScopeGuard.h"
|
||||
@ -59,18 +60,37 @@ Connection::Connection(std::unique_ptr<ISdBus>&& interface, session_bus_t)
|
||||
{
|
||||
}
|
||||
|
||||
Connection::Connection(std::unique_ptr<ISdBus>&& interface, custom_session_bus_t, const std::string& address)
|
||||
: Connection(std::move(interface), [&](sd_bus** bus) { return iface_->sd_bus_open_user_with_address(bus, address.c_str()); })
|
||||
{
|
||||
}
|
||||
|
||||
Connection::Connection(std::unique_ptr<ISdBus>&& interface, remote_system_bus_t, const std::string& host)
|
||||
: Connection(std::move(interface), [this, &host](sd_bus** bus){ return iface_->sd_bus_open_system_remote(bus, host.c_str()); })
|
||||
{
|
||||
}
|
||||
|
||||
Connection::Connection(std::unique_ptr<ISdBus>&& interface, pseudo_bus_t)
|
||||
: iface_(std::move(interface))
|
||||
, bus_(openPseudoBus())
|
||||
{
|
||||
assert(iface_ != nullptr);
|
||||
eventFd_.fd = eventfd(0, 0);
|
||||
assert(eventFd_.fd >= 0);
|
||||
}
|
||||
|
||||
Connection::~Connection()
|
||||
{
|
||||
Connection::leaveEventLoop();
|
||||
if (0 <= eventFd_.fd) {
|
||||
close(eventFd_.fd);
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::requestName(const std::string& name)
|
||||
{
|
||||
SDBUS_CHECK_SERVICE_NAME(name);
|
||||
|
||||
auto r = iface_->sd_bus_request_name(bus_.get(), name.c_str(), 0);
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to request bus name", -r);
|
||||
}
|
||||
@ -126,7 +146,7 @@ Connection::PollData Connection::getEventLoopPollData() const
|
||||
auto r = iface_->sd_bus_get_poll_data(bus_.get(), &pollData);
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to get bus poll data", -r);
|
||||
|
||||
return {pollData.fd, pollData.events, pollData.timeout_usec};
|
||||
return {pollData.fd, pollData.events, pollData.timeout_usec, eventFd_.fd};
|
||||
}
|
||||
|
||||
const ISdBus& Connection::getSdBusInterface() const
|
||||
@ -141,16 +161,21 @@ ISdBus& Connection::getSdBusInterface()
|
||||
|
||||
void Connection::addObjectManager(const std::string& objectPath)
|
||||
{
|
||||
Connection::addObjectManager(objectPath, nullptr);
|
||||
Connection::addObjectManager(objectPath, floating_slot);
|
||||
}
|
||||
|
||||
SlotPtr Connection::addObjectManager(const std::string& objectPath, void* /*dummy*/)
|
||||
void Connection::addObjectManager(const std::string& objectPath, floating_slot_t)
|
||||
{
|
||||
auto r = iface_->sd_bus_add_object_manager(bus_.get(), nullptr, objectPath.c_str());
|
||||
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to add object manager", -r);
|
||||
}
|
||||
|
||||
Slot Connection::addObjectManager(const std::string& objectPath, request_slot_t)
|
||||
{
|
||||
sd_bus_slot *slot{};
|
||||
|
||||
auto r = iface_->sd_bus_add_object_manager( bus_.get()
|
||||
, &slot
|
||||
, objectPath.c_str() );
|
||||
auto r = iface_->sd_bus_add_object_manager(bus_.get(), &slot, objectPath.c_str());
|
||||
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to add object manager", -r);
|
||||
|
||||
@ -175,10 +200,38 @@ uint64_t Connection::getMethodCallTimeout() const
|
||||
return timeout;
|
||||
}
|
||||
|
||||
SlotPtr Connection::addObjectVTable( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const sd_bus_vtable* vtable
|
||||
, void* userData )
|
||||
Slot Connection::addMatch(const std::string& match, message_handler callback)
|
||||
{
|
||||
auto matchInfo = std::make_unique<MatchInfo>(MatchInfo{std::move(callback), *this, {}});
|
||||
|
||||
auto messageHandler = [](sd_bus_message *sdbusMessage, void *userData, sd_bus_error */*retError*/) -> int
|
||||
{
|
||||
auto* matchInfo = static_cast<MatchInfo*>(userData);
|
||||
auto message = Message::Factory::create<PlainMessage>(sdbusMessage, &matchInfo->connection.getSdBusInterface());
|
||||
matchInfo->callback(message);
|
||||
return 0;
|
||||
};
|
||||
|
||||
auto r = iface_->sd_bus_add_match(bus_.get(), &matchInfo->slot, match.c_str(), std::move(messageHandler), matchInfo.get());
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to add match", -r);
|
||||
|
||||
return {matchInfo.release(), [this](void *ptr)
|
||||
{
|
||||
auto* matchInfo = static_cast<MatchInfo*>(ptr);
|
||||
iface_->sd_bus_slot_unref(matchInfo->slot);
|
||||
std::default_delete<MatchInfo>{}(matchInfo);
|
||||
}};
|
||||
}
|
||||
|
||||
void Connection::addMatch(const std::string& match, message_handler callback, floating_slot_t)
|
||||
{
|
||||
floatingMatchRules_.push_back(addMatch(match, std::move(callback)));
|
||||
}
|
||||
|
||||
Slot Connection::addObjectVTable( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const sd_bus_vtable* vtable
|
||||
, void* userData )
|
||||
{
|
||||
sd_bus_slot *slot{};
|
||||
|
||||
@ -293,12 +346,12 @@ void Connection::emitInterfacesRemovedSignal( const std::string& objectPath
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to emit InterfacesRemoved signal", -r);
|
||||
}
|
||||
|
||||
SlotPtr Connection::registerSignalHandler( const std::string& sender
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName
|
||||
, sd_bus_message_handler_t callback
|
||||
, void* userData )
|
||||
Slot Connection::registerSignalHandler( const std::string& sender
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName
|
||||
, sd_bus_message_handler_t callback
|
||||
, void* userData )
|
||||
{
|
||||
sd_bus_slot *slot{};
|
||||
|
||||
@ -353,6 +406,23 @@ Connection::BusPtr Connection::openBus(const BusFactory& busFactory)
|
||||
return busPtr;
|
||||
}
|
||||
|
||||
Connection::BusPtr Connection::openPseudoBus()
|
||||
{
|
||||
sd_bus* bus{};
|
||||
|
||||
int r = iface_->sd_bus_new(&bus);
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to open pseudo bus", -r);
|
||||
|
||||
(void)iface_->sd_bus_start(bus);
|
||||
// It is expected that sd_bus_start has failed here, returning -EINVAL, due to having
|
||||
// not set a bus address, but it will leave the bus in an OPENING state, which enables
|
||||
// us to create plain D-Bus messages as a local data storage (for Variant, for example),
|
||||
// without dependency on real IPC communication with the D-Bus broker daemon.
|
||||
SDBUS_THROW_ERROR_IF(r < 0 && r != -EINVAL, "Failed to start pseudo bus", -r);
|
||||
|
||||
return {bus, [this](sd_bus* bus){ return iface_->sd_bus_close_unref(bus); }};
|
||||
}
|
||||
|
||||
void Connection::finishHandshake(sd_bus* bus)
|
||||
{
|
||||
// Process all requests that are part of the initial handshake,
|
||||
@ -380,6 +450,11 @@ void Connection::notifyEventLoopToExit() const
|
||||
notifyEventLoop(loopExitFd_.fd);
|
||||
}
|
||||
|
||||
void Connection::notifyEventLoop() const
|
||||
{
|
||||
notifyEventLoop(eventFd_.fd);
|
||||
}
|
||||
|
||||
void Connection::notifyEventLoopNewTimeout() const
|
||||
{
|
||||
// The extra notifications for new timeouts are only needed if calls are made asynchronously to the event loop.
|
||||
@ -420,7 +495,7 @@ bool Connection::processPendingRequest()
|
||||
bool Connection::waitForNextRequest()
|
||||
{
|
||||
assert(bus_ != nullptr);
|
||||
assert(eventFd_.fd != 0);
|
||||
assert(eventFd_.fd >= 0);
|
||||
|
||||
auto sdbusPollData = getEventLoopPollData();
|
||||
struct pollfd fds[] = {
|
||||
@ -454,10 +529,10 @@ bool Connection::waitForNextRequest()
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Connection::composeSignalMatchFilter(const std::string &sender,
|
||||
const std::string &objectPath,
|
||||
const std::string &interfaceName,
|
||||
const std::string &signalName)
|
||||
std::string Connection::composeSignalMatchFilter( const std::string &sender
|
||||
, const std::string &objectPath
|
||||
, const std::string &interfaceName
|
||||
, const std::string &signalName )
|
||||
{
|
||||
std::string filter;
|
||||
|
||||
@ -532,10 +607,18 @@ std::unique_ptr<sdbus::internal::IConnection> createConnection()
|
||||
return std::unique_ptr<sdbus::internal::IConnection>(connectionInternal);
|
||||
}
|
||||
|
||||
std::unique_ptr<sdbus::internal::IConnection> createPseudoConnection()
|
||||
{
|
||||
auto interface = std::make_unique<sdbus::internal::SdBus>();
|
||||
return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::pseudo_bus);
|
||||
}
|
||||
|
||||
} // namespace sdbus::internal
|
||||
|
||||
namespace sdbus {
|
||||
|
||||
using internal::Connection;
|
||||
|
||||
std::unique_ptr<sdbus::IConnection> createConnection()
|
||||
{
|
||||
return createSystemBusConnection();
|
||||
@ -549,8 +632,7 @@ std::unique_ptr<sdbus::IConnection> createConnection(const std::string& name)
|
||||
std::unique_ptr<sdbus::IConnection> createDefaultBusConnection()
|
||||
{
|
||||
auto interface = std::make_unique<sdbus::internal::SdBus>();
|
||||
constexpr sdbus::internal::Connection::default_bus_t default_bus;
|
||||
return std::make_unique<sdbus::internal::Connection>(std::move(interface), default_bus);
|
||||
return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::default_bus);
|
||||
}
|
||||
|
||||
std::unique_ptr<sdbus::IConnection> createDefaultBusConnection(const std::string& name)
|
||||
@ -563,8 +645,7 @@ std::unique_ptr<sdbus::IConnection> createDefaultBusConnection(const std::string
|
||||
std::unique_ptr<sdbus::IConnection> createSystemBusConnection()
|
||||
{
|
||||
auto interface = std::make_unique<sdbus::internal::SdBus>();
|
||||
constexpr sdbus::internal::Connection::system_bus_t system_bus;
|
||||
return std::make_unique<sdbus::internal::Connection>(std::move(interface), system_bus);
|
||||
return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::system_bus);
|
||||
}
|
||||
|
||||
std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const std::string& name)
|
||||
@ -577,8 +658,7 @@ std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const std::string&
|
||||
std::unique_ptr<sdbus::IConnection> createSessionBusConnection()
|
||||
{
|
||||
auto interface = std::make_unique<sdbus::internal::SdBus>();
|
||||
constexpr sdbus::internal::Connection::session_bus_t session_bus;
|
||||
return std::make_unique<sdbus::internal::Connection>(std::move(interface), session_bus);
|
||||
return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::session_bus);
|
||||
}
|
||||
|
||||
std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const std::string& name)
|
||||
@ -588,11 +668,17 @@ std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const std::string
|
||||
return conn;
|
||||
}
|
||||
|
||||
std::unique_ptr<sdbus::IConnection> createSessionBusConnectionWithAddress(const std::string &address)
|
||||
{
|
||||
auto interface = std::make_unique<sdbus::internal::SdBus>();
|
||||
assert(interface != nullptr);
|
||||
return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::custom_session_bus, address);
|
||||
}
|
||||
|
||||
std::unique_ptr<sdbus::IConnection> createRemoteSystemBusConnection(const std::string& host)
|
||||
{
|
||||
auto interface = std::make_unique<sdbus::internal::SdBus>();
|
||||
constexpr sdbus::internal::Connection::remote_system_bus_t remote_system_bus;
|
||||
return std::make_unique<sdbus::internal::Connection>(std::move(interface), remote_system_bus, host);
|
||||
return std::make_unique<sdbus::internal::Connection>(std::move(interface), Connection::remote_system_bus, host);
|
||||
}
|
||||
|
||||
} // namespace sdbus
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Connection.h
|
||||
*
|
||||
@ -43,20 +43,29 @@
|
||||
namespace sdbus::internal {
|
||||
|
||||
class Connection final
|
||||
: public sdbus::IConnection // External, public interface
|
||||
, public sdbus::internal::IConnection // Internal, private interface
|
||||
: public sdbus::internal::IConnection
|
||||
{
|
||||
public:
|
||||
// Bus type tags
|
||||
struct default_bus_t{};
|
||||
inline static constexpr default_bus_t default_bus{};
|
||||
struct system_bus_t{};
|
||||
inline static constexpr system_bus_t system_bus{};
|
||||
struct session_bus_t{};
|
||||
inline static constexpr session_bus_t session_bus{};
|
||||
struct custom_session_bus_t{};
|
||||
inline static constexpr custom_session_bus_t custom_session_bus{};
|
||||
struct remote_system_bus_t{};
|
||||
inline static constexpr remote_system_bus_t remote_system_bus{};
|
||||
struct pseudo_bus_t{}; // A bus connection that is not really established with D-Bus daemon
|
||||
inline static constexpr pseudo_bus_t pseudo_bus{};
|
||||
|
||||
Connection(std::unique_ptr<ISdBus>&& interface, default_bus_t);
|
||||
Connection(std::unique_ptr<ISdBus>&& interface, system_bus_t);
|
||||
Connection(std::unique_ptr<ISdBus>&& interface, session_bus_t);
|
||||
Connection(std::unique_ptr<ISdBus>&& interface, custom_session_bus_t, const std::string& address);
|
||||
Connection(std::unique_ptr<ISdBus>&& interface, remote_system_bus_t, const std::string& host);
|
||||
Connection(std::unique_ptr<ISdBus>&& interface, pseudo_bus_t);
|
||||
~Connection() override;
|
||||
|
||||
void requestName(const std::string& name) override;
|
||||
@ -69,18 +78,22 @@ namespace sdbus::internal {
|
||||
bool processPendingRequest() override;
|
||||
|
||||
void addObjectManager(const std::string& objectPath) override;
|
||||
SlotPtr addObjectManager(const std::string& objectPath, void* /*dummy*/) override;
|
||||
void addObjectManager(const std::string& objectPath, floating_slot_t) override;
|
||||
Slot addObjectManager(const std::string& objectPath, request_slot_t) override;
|
||||
|
||||
void setMethodCallTimeout(uint64_t timeout) override;
|
||||
uint64_t getMethodCallTimeout() const override;
|
||||
|
||||
[[nodiscard]] Slot addMatch(const std::string& match, message_handler callback) override;
|
||||
void addMatch(const std::string& match, message_handler callback, floating_slot_t) override;
|
||||
|
||||
const ISdBus& getSdBusInterface() const override;
|
||||
ISdBus& getSdBusInterface() override;
|
||||
|
||||
SlotPtr addObjectVTable( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const sd_bus_vtable* vtable
|
||||
, void* userData ) override;
|
||||
Slot addObjectVTable( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const sd_bus_vtable* vtable
|
||||
, void* userData ) override;
|
||||
|
||||
PlainMessage createPlainMessage() const override;
|
||||
MethodCall createMethodCall( const std::string& destination
|
||||
@ -101,12 +114,12 @@ namespace sdbus::internal {
|
||||
void emitInterfacesRemovedSignal( const std::string& objectPath
|
||||
, const std::vector<std::string>& interfaces ) override;
|
||||
|
||||
SlotPtr registerSignalHandler( const std::string& sender
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName
|
||||
, sd_bus_message_handler_t callback
|
||||
, void* userData ) override;
|
||||
Slot registerSignalHandler( const std::string& sender
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName
|
||||
, sd_bus_message_handler_t callback
|
||||
, void* userData ) override;
|
||||
|
||||
MethodReply tryCallMethodSynchronously(const MethodCall& message, uint64_t timeout) override;
|
||||
|
||||
@ -116,14 +129,17 @@ namespace sdbus::internal {
|
||||
Connection(std::unique_ptr<ISdBus>&& interface, const BusFactory& busFactory);
|
||||
|
||||
BusPtr openBus(const std::function<int(sd_bus**)>& busFactory);
|
||||
BusPtr openPseudoBus();
|
||||
void finishHandshake(sd_bus* bus);
|
||||
bool waitForNextRequest();
|
||||
static std::string composeSignalMatchFilter(const std::string &sender, const std::string &objectPath,
|
||||
const std::string &interfaceName,
|
||||
const std::string &signalName);
|
||||
static std::string composeSignalMatchFilter( const std::string &sender
|
||||
, const std::string &objectPath
|
||||
, const std::string &interfaceName
|
||||
, const std::string &signalName);
|
||||
void notifyEventLoop(int fd) const;
|
||||
void notifyEventLoopToExit() const;
|
||||
void clearEventLoopNotification(int fd) const;
|
||||
void notifyEventLoop() const override;
|
||||
void notifyEventLoopNewTimeout() const override;
|
||||
|
||||
private:
|
||||
@ -134,7 +150,14 @@ namespace sdbus::internal {
|
||||
{
|
||||
EventFd();
|
||||
~EventFd();
|
||||
int fd;
|
||||
int fd{-1};
|
||||
};
|
||||
|
||||
struct MatchInfo
|
||||
{
|
||||
message_handler callback;
|
||||
Connection& connection;
|
||||
sd_bus_slot *slot;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -146,6 +169,7 @@ namespace sdbus::internal {
|
||||
EventFd loopExitFd_;
|
||||
EventFd eventFd_;
|
||||
std::atomic<uint64_t> activeTimeout_{};
|
||||
std::vector<Slot> floatingMatchRules_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Error.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Flags.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file IConnection.h
|
||||
*
|
||||
@ -27,6 +27,7 @@
|
||||
#ifndef SDBUS_CXX_INTERNAL_ICONNECTION_H_
|
||||
#define SDBUS_CXX_INTERNAL_ICONNECTION_H_
|
||||
|
||||
#include <sdbus-c++/IConnection.h>
|
||||
#include <systemd/sd-bus.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
@ -46,20 +47,19 @@ namespace sdbus {
|
||||
|
||||
namespace sdbus::internal {
|
||||
|
||||
using SlotPtr = std::unique_ptr<void, std::function<void(void*)>>;
|
||||
|
||||
class IConnection
|
||||
: public ::sdbus::IConnection
|
||||
{
|
||||
public:
|
||||
virtual ~IConnection() = default;
|
||||
~IConnection() override = default;
|
||||
|
||||
virtual const ISdBus& getSdBusInterface() const = 0;
|
||||
virtual ISdBus& getSdBusInterface() = 0;
|
||||
|
||||
[[nodiscard]] virtual SlotPtr addObjectVTable( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const sd_bus_vtable* vtable
|
||||
, void* userData ) = 0;
|
||||
[[nodiscard]] virtual Slot addObjectVTable( const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const sd_bus_vtable* vtable
|
||||
, void* userData ) = 0;
|
||||
|
||||
virtual PlainMessage createPlainMessage() const = 0;
|
||||
virtual MethodCall createMethodCall( const std::string& destination
|
||||
@ -80,22 +80,23 @@ namespace sdbus::internal {
|
||||
virtual void emitInterfacesRemovedSignal( const std::string& objectPath
|
||||
, const std::vector<std::string>& interfaces ) = 0;
|
||||
|
||||
[[nodiscard]] virtual SlotPtr addObjectManager(const std::string& objectPath, void* /*dummy*/ = nullptr) = 0;
|
||||
using sdbus::IConnection::addObjectManager;
|
||||
[[nodiscard]] virtual Slot addObjectManager(const std::string& objectPath, request_slot_t) = 0;
|
||||
|
||||
[[nodiscard]] virtual SlotPtr registerSignalHandler( const std::string& sender
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName
|
||||
, sd_bus_message_handler_t callback
|
||||
, void* userData ) = 0;
|
||||
[[nodiscard]] virtual Slot registerSignalHandler( const std::string& sender
|
||||
, const std::string& objectPath
|
||||
, const std::string& interfaceName
|
||||
, const std::string& signalName
|
||||
, sd_bus_message_handler_t callback
|
||||
, void* userData ) = 0;
|
||||
|
||||
virtual void enterEventLoopAsync() = 0;
|
||||
virtual void leaveEventLoop() = 0;
|
||||
virtual void notifyEventLoop() const = 0;
|
||||
virtual void notifyEventLoopNewTimeout() const = 0;
|
||||
virtual MethodReply tryCallMethodSynchronously(const MethodCall& message, uint64_t timeout) = 0;
|
||||
};
|
||||
|
||||
[[nodiscard]] std::unique_ptr<sdbus::internal::IConnection> createConnection();
|
||||
[[nodiscard]] std::unique_ptr<sdbus::internal::IConnection> createPseudoConnection();
|
||||
|
||||
}
|
||||
|
||||
|
11
src/ISdBus.h
11
src/ISdBus.h
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file ISdBus.h
|
||||
* @author Ardazishvili Roman (ardazishvili.roman@yandex.ru)
|
||||
@ -67,8 +67,9 @@ namespace sdbus::internal {
|
||||
virtual int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, char **interfaces) = 0;
|
||||
|
||||
virtual int sd_bus_open(sd_bus **ret) = 0;
|
||||
virtual int sd_bus_open_user(sd_bus **ret) = 0;
|
||||
virtual int sd_bus_open_system(sd_bus **ret) = 0;
|
||||
virtual int sd_bus_open_user(sd_bus **ret) = 0;
|
||||
virtual int sd_bus_open_user_with_address(sd_bus **ret, const char* address) = 0;
|
||||
virtual int sd_bus_open_system_remote(sd_bus **ret, const char* host) = 0;
|
||||
virtual int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) = 0;
|
||||
virtual int sd_bus_release_name(sd_bus *bus, const char *name) = 0;
|
||||
@ -78,11 +79,15 @@ namespace sdbus::internal {
|
||||
virtual int sd_bus_add_match(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata) = 0;
|
||||
virtual sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) = 0;
|
||||
|
||||
virtual int sd_bus_new(sd_bus **ret) = 0;
|
||||
virtual int sd_bus_start(sd_bus *bus) = 0;
|
||||
|
||||
virtual int sd_bus_process(sd_bus *bus, sd_bus_message **r) = 0;
|
||||
virtual int sd_bus_get_poll_data(sd_bus *bus, PollData* data) = 0;
|
||||
|
||||
virtual int sd_bus_flush(sd_bus *bus) = 0;
|
||||
virtual sd_bus *sd_bus_flush_close_unref(sd_bus *bus) = 0;
|
||||
virtual sd_bus *sd_bus_close_unref(sd_bus *bus) = 0;
|
||||
|
||||
virtual int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) = 0;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Message.cpp
|
||||
*
|
||||
@ -782,6 +782,10 @@ MethodReply MethodCall::sendWithReply(uint64_t timeout) const
|
||||
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method", -r);
|
||||
|
||||
// Force event loop to re-enter processing to handle queued messages
|
||||
SDBUS_THROW_ERROR_IF(connection_ == nullptr, "Invalid use of MethodCall API", ENOTSUP);
|
||||
connection_->notifyEventLoop();
|
||||
|
||||
return Factory::create<MethodReply>(sdbusReply, sdbus_, adopt_message);
|
||||
}
|
||||
|
||||
@ -790,10 +794,19 @@ MethodReply MethodCall::sendWithNoReply() const
|
||||
auto r = sdbus_->sd_bus_send(nullptr, (sd_bus_message*)msg_, nullptr);
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method with no reply", -r);
|
||||
|
||||
// Force event loop to re-enter processing to handle queued messages
|
||||
SDBUS_THROW_ERROR_IF(connection_ == nullptr, "Invalid use of MethodCall API", ENOTSUP);
|
||||
connection_->notifyEventLoop();
|
||||
|
||||
return Factory::create<MethodReply>(); // No reply
|
||||
}
|
||||
|
||||
void MethodCall::send(void* callback, void* userData, uint64_t timeout, dont_request_slot_t) const
|
||||
{
|
||||
MethodCall::send(callback, userData, timeout, floating_slot);
|
||||
}
|
||||
|
||||
void MethodCall::send(void* callback, void* userData, uint64_t timeout, floating_slot_t) const
|
||||
{
|
||||
auto r = sdbus_->sd_bus_call_async(nullptr, nullptr, (sd_bus_message*)msg_, (sd_bus_message_handler_t)callback, userData, timeout);
|
||||
SDBUS_THROW_ERROR_IF(r < 0, "Failed to call method", -r);
|
||||
@ -803,7 +816,7 @@ void MethodCall::send(void* callback, void* userData, uint64_t timeout, dont_req
|
||||
connection_->notifyEventLoopNewTimeout();
|
||||
}
|
||||
|
||||
MethodCall::Slot MethodCall::send(void* callback, void* userData, uint64_t timeout) const
|
||||
Slot MethodCall::send(void* callback, void* userData, uint64_t timeout) const
|
||||
{
|
||||
sd_bus_slot* slot;
|
||||
|
||||
@ -814,7 +827,7 @@ MethodCall::Slot MethodCall::send(void* callback, void* userData, uint64_t timeo
|
||||
SDBUS_THROW_ERROR_IF(connection_ == nullptr, "Invalid use of MethodCall API", ENOTSUP);
|
||||
connection_->notifyEventLoopNewTimeout();
|
||||
|
||||
return Slot{slot, [sdbus_ = sdbus_](void *slot){ sdbus_->sd_bus_slot_unref((sd_bus_slot*)slot); }};
|
||||
return {slot, [sdbus_ = sdbus_](void *slot){ sdbus_->sd_bus_slot_unref((sd_bus_slot*)slot); }};
|
||||
}
|
||||
|
||||
MethodReply MethodCall::createReply() const
|
||||
@ -859,9 +872,13 @@ void Signal::setDestination(const std::string& destination)
|
||||
|
||||
PlainMessage createPlainMessage()
|
||||
{
|
||||
static auto connection = internal::createConnection();
|
||||
//static auto connection = internal::createConnection();
|
||||
// Let's create a pseudo connection -- one that does not really connect to the real bus.
|
||||
// This is a bit of a hack, but it enables use to work with D-Bus message locally without
|
||||
// the need of D-Bus daemon. This is especially useful in unit tests of both sdbus-c++ and client code.
|
||||
// Additionally, it's light-weight and fast solution.
|
||||
static auto connection = internal::createPseudoConnection();
|
||||
return connection->createPlainMessage();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file MessageUtils.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Object.cpp
|
||||
*
|
||||
@ -33,6 +33,7 @@
|
||||
#include <sdbus-c++/Flags.h>
|
||||
#include "ScopeGuard.h"
|
||||
#include "IConnection.h"
|
||||
#include "Utils.h"
|
||||
#include "VTableUtils.h"
|
||||
#include <systemd/sd-bus.h>
|
||||
#include <utility>
|
||||
@ -43,6 +44,7 @@ namespace sdbus::internal {
|
||||
Object::Object(sdbus::internal::IConnection& connection, std::string objectPath)
|
||||
: connection_(connection), objectPath_(std::move(objectPath))
|
||||
{
|
||||
SDBUS_CHECK_OBJECT_PATH(objectPath_);
|
||||
}
|
||||
|
||||
void Object::registerMethod( const std::string& interfaceName
|
||||
@ -71,6 +73,8 @@ void Object::registerMethod( const std::string& interfaceName
|
||||
, method_callback methodCallback
|
||||
, Flags flags )
|
||||
{
|
||||
SDBUS_CHECK_INTERFACE_NAME(interfaceName);
|
||||
SDBUS_CHECK_MEMBER_NAME(methodName);
|
||||
SDBUS_THROW_ERROR_IF(!methodCallback, "Invalid method callback provided", EINVAL);
|
||||
|
||||
auto& interface = getInterface(interfaceName);
|
||||
@ -98,6 +102,9 @@ void Object::registerSignal( const std::string& interfaceName
|
||||
, const std::vector<std::string>& paramNames
|
||||
, Flags flags )
|
||||
{
|
||||
SDBUS_CHECK_INTERFACE_NAME(interfaceName);
|
||||
SDBUS_CHECK_MEMBER_NAME(signalName);
|
||||
|
||||
auto& interface = getInterface(interfaceName);
|
||||
|
||||
InterfaceData::SignalData signalData{std::move(signature), paramNamesToString(paramNames), std::move(flags)};
|
||||
@ -127,6 +134,8 @@ void Object::registerProperty( const std::string& interfaceName
|
||||
, property_set_callback setCallback
|
||||
, Flags flags )
|
||||
{
|
||||
SDBUS_CHECK_INTERFACE_NAME(interfaceName);
|
||||
SDBUS_CHECK_MEMBER_NAME(propertyName);
|
||||
SDBUS_THROW_ERROR_IF(!getCallback && !setCallback, "Invalid property callbacks provided", EINVAL);
|
||||
|
||||
auto& interface = getInterface(interfaceName);
|
||||
@ -208,7 +217,7 @@ void Object::emitInterfacesRemovedSignal(const std::vector<std::string>& interfa
|
||||
|
||||
void Object::addObjectManager()
|
||||
{
|
||||
objectManagerSlot_ = connection_.addObjectManager(objectPath_);
|
||||
objectManagerSlot_ = connection_.addObjectManager(objectPath_, request_slot);
|
||||
}
|
||||
|
||||
void Object::removeObjectManager()
|
||||
@ -223,7 +232,7 @@ bool Object::hasObjectManager() const
|
||||
|
||||
sdbus::IConnection& Object::getConnection() const
|
||||
{
|
||||
return dynamic_cast<sdbus::IConnection&>(connection_);
|
||||
return connection_;
|
||||
}
|
||||
|
||||
const std::string& Object::getObjectPath() const
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Object.h
|
||||
*
|
||||
@ -144,7 +144,7 @@ namespace sdbus::internal {
|
||||
|
||||
// This is intentionally the last member, because it must be destructed first,
|
||||
// releasing callbacks above before the callbacks themselves are destructed.
|
||||
SlotPtr slot;
|
||||
Slot slot;
|
||||
};
|
||||
|
||||
InterfaceData& getInterface(const std::string& interfaceName);
|
||||
@ -177,7 +177,7 @@ namespace sdbus::internal {
|
||||
sdbus::internal::IConnection& connection_;
|
||||
std::string objectPath_;
|
||||
std::map<InterfaceName, InterfaceData> interfaces_;
|
||||
SlotPtr objectManagerSlot_;
|
||||
Slot objectManagerSlot_;
|
||||
std::atomic<const Message*> m_CurrentlyProcessedMessage{nullptr};
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Proxy.cpp
|
||||
*
|
||||
@ -27,6 +27,7 @@
|
||||
#include "Proxy.h"
|
||||
#include "IConnection.h"
|
||||
#include "MessageUtils.h"
|
||||
#include "Utils.h"
|
||||
#include "sdbus-c++/Message.h"
|
||||
#include "sdbus-c++/IConnection.h"
|
||||
#include "sdbus-c++/Error.h"
|
||||
@ -43,6 +44,9 @@ Proxy::Proxy(sdbus::internal::IConnection& connection, std::string destination,
|
||||
, destination_(std::move(destination))
|
||||
, objectPath_(std::move(objectPath))
|
||||
{
|
||||
SDBUS_CHECK_SERVICE_NAME(destination_);
|
||||
SDBUS_CHECK_OBJECT_PATH(objectPath_);
|
||||
|
||||
// The connection is not ours only, it is owned and managed by the user and we just reference
|
||||
// it here, so we expect the client to manage the event loop upon this connection themselves.
|
||||
}
|
||||
@ -54,6 +58,9 @@ Proxy::Proxy( std::unique_ptr<sdbus::internal::IConnection>&& connection
|
||||
, destination_(std::move(destination))
|
||||
, objectPath_(std::move(objectPath))
|
||||
{
|
||||
SDBUS_CHECK_SERVICE_NAME(destination_);
|
||||
SDBUS_CHECK_OBJECT_PATH(objectPath_);
|
||||
|
||||
// The connection is ours only, i.e. it's us who has to manage the event loop upon this connection,
|
||||
// in order that we get and process signals, async call replies, and other messages from D-Bus.
|
||||
connection_->enterEventLoopAsync();
|
||||
@ -120,7 +127,7 @@ MethodReply Proxy::sendMethodCallMessageAndWaitForReply(const MethodCall& messag
|
||||
auto callback = (void*)&Proxy::sdbus_async_reply_handler;
|
||||
AsyncCalls::CallData callData{*this, std::move(asyncReplyCallback), {}};
|
||||
|
||||
message.send(callback, &callData, timeout, dont_request_slot);
|
||||
message.send(callback, &callData, timeout, floating_slot);
|
||||
|
||||
return syncCallReplyData.waitForMethodReply();
|
||||
}
|
||||
@ -156,6 +163,8 @@ void Proxy::registerSignalHandler( const std::string& interfaceName
|
||||
, const std::string& signalName
|
||||
, signal_handler signalHandler )
|
||||
{
|
||||
SDBUS_CHECK_INTERFACE_NAME(interfaceName);
|
||||
SDBUS_CHECK_MEMBER_NAME(signalName);
|
||||
SDBUS_THROW_ERROR_IF(!signalHandler, "Invalid signal handler provided", EINVAL);
|
||||
|
||||
auto& interface = interfaces_[interfaceName];
|
||||
@ -210,7 +219,7 @@ void Proxy::unregister()
|
||||
|
||||
sdbus::IConnection& Proxy::getConnection() const
|
||||
{
|
||||
return dynamic_cast<sdbus::IConnection&>(*connection_);
|
||||
return *connection_;
|
||||
}
|
||||
|
||||
const std::string& Proxy::getObjectPath() const
|
||||
@ -267,7 +276,7 @@ int Proxy::sdbus_async_reply_handler(sd_bus_message *sdbusMessage, void *userDat
|
||||
// Intentionally left blank -- sdbus-c++ exceptions shall not bubble up to the underlying C sd-bus library
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Proxy::sdbus_signal_handler(sd_bus_message *sdbusMessage, void *userData, sd_bus_error */*retError*/)
|
||||
|
14
src/Proxy.h
14
src/Proxy.h
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Proxy.h
|
||||
*
|
||||
@ -103,18 +103,18 @@ namespace sdbus::internal {
|
||||
using SignalName = std::string;
|
||||
struct SignalData
|
||||
{
|
||||
SignalData(Proxy& proxy, signal_handler callback, SlotPtr slot)
|
||||
SignalData(Proxy& proxy, signal_handler callback, Slot slot)
|
||||
: proxy(proxy)
|
||||
, callback(std::move(callback))
|
||||
, slot(std::move(slot))
|
||||
{}
|
||||
Proxy& proxy;
|
||||
signal_handler callback;
|
||||
// slot_ must be listed after callback_ to ensure that slot_ is destructed first.
|
||||
// Destructing the slot_ will sd_bus_slot_unref() the callback.
|
||||
// slot must be listed after callback to ensure that slot is destructed first.
|
||||
// Destructing the slot will sd_bus_slot_unref() the callback.
|
||||
// Only after sd_bus_slot_unref(), we can safely delete the callback. The bus mutex (SdBus::sdbusMutex_)
|
||||
// ensures that sd_bus_slot_unref() and the callback execute sequentially.
|
||||
SlotPtr slot;
|
||||
Slot slot;
|
||||
};
|
||||
std::map<SignalName, std::unique_ptr<SignalData>> signals_;
|
||||
};
|
||||
@ -131,7 +131,7 @@ namespace sdbus::internal {
|
||||
{
|
||||
Proxy& proxy;
|
||||
async_reply_handler callback;
|
||||
MethodCall::Slot slot;
|
||||
Slot slot;
|
||||
};
|
||||
|
||||
~AsyncCalls()
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file ScopeGuard.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file SdBus.cpp
|
||||
* @author Ardazishvili Roman (ardazishvili.roman@yandex.ru)
|
||||
@ -166,14 +166,46 @@ int SdBus::sd_bus_open(sd_bus **ret)
|
||||
return ::sd_bus_open(ret);
|
||||
}
|
||||
|
||||
int SdBus::sd_bus_open_system(sd_bus **ret)
|
||||
{
|
||||
return ::sd_bus_open_system(ret);
|
||||
}
|
||||
|
||||
int SdBus::sd_bus_open_user(sd_bus **ret)
|
||||
{
|
||||
return ::sd_bus_open_user(ret);
|
||||
}
|
||||
|
||||
int SdBus::sd_bus_open_system(sd_bus **ret)
|
||||
int SdBus::sd_bus_open_user_with_address(sd_bus **ret, const char* address)
|
||||
{
|
||||
return ::sd_bus_open_system(ret);
|
||||
sd_bus* bus = nullptr;
|
||||
|
||||
int r = sd_bus_new(&bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_set_address(bus, address);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_set_bus_client(bus, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
// Copying behavior from
|
||||
// https://github.com/systemd/systemd/blob/fee6441601c979165ebcbb35472036439f8dad5f/src/libsystemd/sd-bus/sd-bus.c#L1381
|
||||
// Here, we make the bus as trusted
|
||||
r = sd_bus_set_trusted(bus, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_start(bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SdBus::sd_bus_open_system_remote(sd_bus **ret, const char *host)
|
||||
@ -229,6 +261,16 @@ sd_bus_slot* SdBus::sd_bus_slot_unref(sd_bus_slot *slot)
|
||||
return ::sd_bus_slot_unref(slot);
|
||||
}
|
||||
|
||||
int SdBus::sd_bus_new(sd_bus **ret)
|
||||
{
|
||||
return ::sd_bus_new(ret);
|
||||
}
|
||||
|
||||
int SdBus::sd_bus_start(sd_bus *bus)
|
||||
{
|
||||
return ::sd_bus_start(bus);
|
||||
}
|
||||
|
||||
int SdBus::sd_bus_process(sd_bus *bus, sd_bus_message **r)
|
||||
{
|
||||
std::lock_guard lock(sdbusMutex_);
|
||||
@ -265,6 +307,16 @@ sd_bus* SdBus::sd_bus_flush_close_unref(sd_bus *bus)
|
||||
return ::sd_bus_flush_close_unref(bus);
|
||||
}
|
||||
|
||||
sd_bus* SdBus::sd_bus_close_unref(sd_bus *bus)
|
||||
{
|
||||
#if LIBSYSTEMD_VERSION>=241
|
||||
return ::sd_bus_close_unref(bus);
|
||||
#else
|
||||
::sd_bus_close(bus);
|
||||
return ::sd_bus_unref(bus);
|
||||
#endif
|
||||
}
|
||||
|
||||
int SdBus::sd_bus_message_set_destination(sd_bus_message *m, const char *destination)
|
||||
{
|
||||
std::lock_guard lock(sdbusMutex_);
|
||||
|
11
src/SdBus.h
11
src/SdBus.h
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file SdBus.h
|
||||
* @author Ardazishvili Roman (ardazishvili.roman@yandex.ru)
|
||||
@ -59,8 +59,9 @@ public:
|
||||
virtual int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, char **interfaces) override;
|
||||
|
||||
virtual int sd_bus_open(sd_bus **ret) override;
|
||||
virtual int sd_bus_open_user(sd_bus **ret) override;
|
||||
virtual int sd_bus_open_system(sd_bus **ret) override;
|
||||
virtual int sd_bus_open_user(sd_bus **ret) override;
|
||||
virtual int sd_bus_open_user_with_address(sd_bus **ret, const char* address) override;
|
||||
virtual int sd_bus_open_system_remote(sd_bus **ret, const char* hsot) override;
|
||||
virtual int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) override;
|
||||
virtual int sd_bus_release_name(sd_bus *bus, const char *name) override;
|
||||
@ -70,11 +71,15 @@ public:
|
||||
virtual int sd_bus_add_match(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata) override;
|
||||
virtual sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) override;
|
||||
|
||||
virtual int sd_bus_new(sd_bus **ret) override;
|
||||
virtual int sd_bus_start(sd_bus *bus) override;
|
||||
|
||||
virtual int sd_bus_process(sd_bus *bus, sd_bus_message **r) override;
|
||||
virtual int sd_bus_get_poll_data(sd_bus *bus, PollData* data) override;
|
||||
|
||||
virtual int sd_bus_flush(sd_bus *bus) override;
|
||||
virtual sd_bus *sd_bus_flush_close_unref(sd_bus *bus) override;
|
||||
virtual sd_bus *sd_bus_close_unref(sd_bus *bus) override;
|
||||
|
||||
virtual int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) override;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Types.cpp
|
||||
*
|
||||
|
53
src/Utils.h
Normal file
53
src/Utils.h
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Utils.h
|
||||
*
|
||||
* Created on: Feb 9, 2022
|
||||
* 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_INTERNAL_UTILS_H_
|
||||
#define SDBUS_CXX_INTERNAL_UTILS_H_
|
||||
|
||||
#include <sdbus-c++/Error.h>
|
||||
#include <systemd/sd-bus.h>
|
||||
|
||||
#if LIBSYSTEMD_VERSION>=246
|
||||
#define SDBUS_CHECK_OBJECT_PATH(_PATH) \
|
||||
SDBUS_THROW_ERROR_IF(!sd_bus_object_path_is_valid(_PATH.c_str()), "Invalid object path '" + _PATH + "' provided", EINVAL) \
|
||||
/**/
|
||||
#define SDBUS_CHECK_INTERFACE_NAME(_NAME) \
|
||||
SDBUS_THROW_ERROR_IF(!sd_bus_interface_name_is_valid(_NAME.c_str()), "Invalid interface name '" + _NAME + "' provided", EINVAL) \
|
||||
/**/
|
||||
#define SDBUS_CHECK_SERVICE_NAME(_NAME) \
|
||||
SDBUS_THROW_ERROR_IF(!sd_bus_service_name_is_valid(_NAME.c_str()), "Invalid service name '" + _NAME + "' provided", EINVAL) \
|
||||
/**/
|
||||
#define SDBUS_CHECK_MEMBER_NAME(_NAME) \
|
||||
SDBUS_THROW_ERROR_IF(!sd_bus_member_name_is_valid(_NAME.c_str()), "Invalid member name '" + _NAME + "' provided", EINVAL) \
|
||||
/**/
|
||||
#else
|
||||
#define SDBUS_CHECK_OBJECT_PATH(_PATH)
|
||||
#define SDBUS_CHECK_INTERFACE_NAME(_NAME)
|
||||
#define SDBUS_CHECK_SERVICE_NAME(_NAME)
|
||||
#define SDBUS_CHECK_MEMBER_NAME(_NAME)
|
||||
#endif
|
||||
|
||||
#endif /* SDBUS_CXX_INTERNAL_UTILS_H_ */
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file VTableUtils.c
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file VTableUtils.h
|
||||
*
|
||||
|
@ -19,7 +19,7 @@ if (NOT TARGET GTest::gmock)
|
||||
if (NOT TARGET GTest::gmock)
|
||||
include(FetchContent)
|
||||
|
||||
message("Fetching googletest...")
|
||||
message("Fetching googletest v${GOOGLETEST_VERSION}...")
|
||||
FetchContent_Declare(googletest
|
||||
GIT_REPOSITORY ${GOOGLETEST_GIT_REPO}
|
||||
GIT_TAG release-${GOOGLETEST_VERSION}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2020 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file DBusAsyncMethodsTests.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2020 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file DBusConnectionTests.cpp
|
||||
*
|
||||
@ -130,4 +130,4 @@ TEST(Connection, PollDataGetRelativeTimeoutInTolerance)
|
||||
EXPECT_LE(pd.getRelativeTimeout().value(), TIMEOUT + TOLERANCE);
|
||||
EXPECT_GE(pd.getPollTimeout(), 900);
|
||||
EXPECT_LE(pd.getPollTimeout(), 1100);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2020 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file DBusGeneralTests.cpp
|
||||
*
|
||||
@ -26,6 +26,7 @@
|
||||
|
||||
#include "TestAdaptor.h"
|
||||
#include "TestProxy.h"
|
||||
#include "TestFixture.h"
|
||||
#include "sdbus-c++/sdbus-c++.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
@ -38,8 +39,13 @@
|
||||
#include <future>
|
||||
#include <unistd.h>
|
||||
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Eq;
|
||||
using namespace std::chrono_literals;
|
||||
using namespace sdbus::test;
|
||||
|
||||
using AConnection = TestFixture;
|
||||
|
||||
/*-------------------------------------*/
|
||||
/* -- TEST CASES -- */
|
||||
/*-------------------------------------*/
|
||||
@ -52,3 +58,75 @@ TEST(AdaptorAndProxy, CanBeConstructedSuccesfully)
|
||||
ASSERT_NO_THROW(TestAdaptor adaptor(*connection, OBJECT_PATH));
|
||||
ASSERT_NO_THROW(TestProxy proxy(BUS_NAME, OBJECT_PATH));
|
||||
}
|
||||
|
||||
TEST_F(AConnection, WillCallCallbackHandlerForIncomingMessageMatchingMatchRule)
|
||||
{
|
||||
auto matchRule = "sender='" + BUS_NAME + "',path='" + OBJECT_PATH + "'";
|
||||
std::atomic<bool> matchingMessageReceived{false};
|
||||
auto slot = s_proxyConnection->addMatch(matchRule, [&](sdbus::Message& msg)
|
||||
{
|
||||
if(msg.getPath() == OBJECT_PATH)
|
||||
matchingMessageReceived = true;
|
||||
});
|
||||
|
||||
m_adaptor->emitSimpleSignal();
|
||||
|
||||
ASSERT_TRUE(waitUntil(matchingMessageReceived));
|
||||
}
|
||||
|
||||
TEST_F(AConnection, WillUnsubscribeMatchRuleWhenClientDestroysTheAssociatedSlot)
|
||||
{
|
||||
auto matchRule = "sender='" + BUS_NAME + "',path='" + OBJECT_PATH + "'";
|
||||
std::atomic<bool> matchingMessageReceived{false};
|
||||
auto slot = s_proxyConnection->addMatch(matchRule, [&](sdbus::Message& msg)
|
||||
{
|
||||
if(msg.getPath() == OBJECT_PATH)
|
||||
matchingMessageReceived = true;
|
||||
});
|
||||
slot.reset();
|
||||
|
||||
m_adaptor->emitSimpleSignal();
|
||||
|
||||
ASSERT_FALSE(waitUntil(matchingMessageReceived, 2s));
|
||||
}
|
||||
|
||||
TEST_F(AConnection, CanAddFloatingMatchRule)
|
||||
{
|
||||
auto matchRule = "sender='" + BUS_NAME + "',path='" + OBJECT_PATH + "'";
|
||||
std::atomic<bool> matchingMessageReceived{false};
|
||||
auto con = sdbus::createSystemBusConnection();
|
||||
con->enterEventLoopAsync();
|
||||
auto callback = [&](sdbus::Message& msg)
|
||||
{
|
||||
if(msg.getPath() == OBJECT_PATH)
|
||||
matchingMessageReceived = true;
|
||||
};
|
||||
con->addMatch(matchRule, std::move(callback), sdbus::floating_slot);
|
||||
m_adaptor->emitSimpleSignal();
|
||||
assert(waitUntil(matchingMessageReceived, 2s));
|
||||
matchingMessageReceived = false;
|
||||
|
||||
con.reset();
|
||||
m_adaptor->emitSimpleSignal();
|
||||
|
||||
ASSERT_FALSE(waitUntil(matchingMessageReceived, 2s));
|
||||
}
|
||||
|
||||
TEST_F(AConnection, WillNotPassToMatchCallbackMessagesThatDoNotMatchTheRule)
|
||||
{
|
||||
auto matchRule = "type='signal',interface='" + INTERFACE_NAME + "',member='simpleSignal'";
|
||||
std::atomic<size_t> numberOfMatchingMessages{};
|
||||
auto slot = s_proxyConnection->addMatch(matchRule, [&](sdbus::Message& msg)
|
||||
{
|
||||
if(msg.getMemberName() == "simpleSignal")
|
||||
numberOfMatchingMessages++;
|
||||
});
|
||||
auto adaptor2 = std::make_unique<TestAdaptor>(*s_adaptorConnection, OBJECT_PATH_2);
|
||||
|
||||
m_adaptor->emitSignalWithMap({});
|
||||
adaptor2->emitSimpleSignal();
|
||||
m_adaptor->emitSimpleSignal();
|
||||
|
||||
ASSERT_TRUE(waitUntil([&](){ return numberOfMatchingMessages == 2; }));
|
||||
ASSERT_FALSE(waitUntil([&](){ return numberOfMatchingMessages > 2; }, 1s));
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2020 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file DBusMethodsTests.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2020 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file DBusPropertiesTests.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file AdaptorAndProxy_test.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2020 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file DBusStandardInterfacesTests.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Defs.h
|
||||
*
|
||||
@ -56,20 +56,18 @@ const bool DEFAULT_BLOCKING_VALUE{true};
|
||||
|
||||
constexpr const double DOUBLE_VALUE{3.24L};
|
||||
|
||||
/** Duration stream operator for human readable gtest value output.
|
||||
*
|
||||
* Note that the conversion to double is lossy if the input type has 64 or more bits.
|
||||
* This is ok for our integration tests because they don't have very
|
||||
* accurate timing requirements.
|
||||
*
|
||||
* @return human readable duration in seconds
|
||||
*/
|
||||
template< class Rep, class Period >
|
||||
static std::ostream& operator<<(std::ostream& os, const std::chrono::duration<Rep, Period>& d)
|
||||
{
|
||||
auto seconds = std::chrono::duration_cast<std::chrono::duration<double>>(d);
|
||||
return os << seconds.count() << " s";
|
||||
}
|
||||
}}
|
||||
|
||||
namespace testing::internal {
|
||||
|
||||
// Printer for std::chrono::duration types.
|
||||
// This is a workaround, since it's not a good thing to add this to std namespace.
|
||||
template< class Rep, class Period >
|
||||
void PrintTo(const ::std::chrono::duration<Rep, Period>& d, ::std::ostream* os) {
|
||||
auto seconds = std::chrono::duration_cast<std::chrono::duration<double>>(d);
|
||||
*os << seconds.count() << "s";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* SDBUS_CPP_INTEGRATIONTESTS_DEFS_H_ */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file TestAdaptor.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file TestAdaptor.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file TestAdaptor.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file TestAdaptor.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file TestAdaptor.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file TestAdaptor.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file sdbus-c++-integration-tests.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Connection_test.cpp
|
||||
* @author Ardazishvili Roman (ardazishvili.roman@yandex.ru)
|
||||
@ -35,11 +35,7 @@ using ::testing::DoAll;
|
||||
using ::testing::SetArgPointee;
|
||||
using ::testing::Return;
|
||||
using ::testing::NiceMock;
|
||||
using sdbus::internal::Connection;
|
||||
constexpr sdbus::internal::Connection::default_bus_t default_bus;
|
||||
constexpr sdbus::internal::Connection::system_bus_t system_bus;
|
||||
constexpr sdbus::internal::Connection::session_bus_t session_bus;
|
||||
constexpr sdbus::internal::Connection::remote_system_bus_t remote_system_bus;
|
||||
using ::sdbus::internal::Connection;
|
||||
|
||||
class ConnectionCreationTest : public ::testing::Test
|
||||
{
|
||||
@ -58,81 +54,81 @@ TEST_F(ADefaultBusConnection, OpensAndFlushesBusWhenCreated)
|
||||
{
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1);
|
||||
Connection(std::move(sdBusIntfMock_), default_bus);
|
||||
Connection(std::move(sdBusIntfMock_), Connection::default_bus);
|
||||
}
|
||||
|
||||
TEST_F(ASystemBusConnection, OpensAndFlushesBusWhenCreated)
|
||||
{
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1);
|
||||
Connection(std::move(sdBusIntfMock_), system_bus);
|
||||
Connection(std::move(sdBusIntfMock_), Connection::system_bus);
|
||||
}
|
||||
|
||||
TEST_F(ASessionBusConnection, OpensAndFlushesBusWhenCreated)
|
||||
{
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush(_)).Times(1);
|
||||
Connection(std::move(sdBusIntfMock_), session_bus);
|
||||
Connection(std::move(sdBusIntfMock_), Connection::session_bus);
|
||||
}
|
||||
|
||||
TEST_F(ADefaultBusConnection, ClosesAndUnrefsBusWhenDestructed)
|
||||
{
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1);
|
||||
Connection(std::move(sdBusIntfMock_), default_bus);
|
||||
Connection(std::move(sdBusIntfMock_), Connection::default_bus);
|
||||
}
|
||||
|
||||
TEST_F(ASystemBusConnection, ClosesAndUnrefsBusWhenDestructed)
|
||||
{
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1);
|
||||
Connection(std::move(sdBusIntfMock_), system_bus);
|
||||
Connection(std::move(sdBusIntfMock_), Connection::system_bus);
|
||||
}
|
||||
|
||||
TEST_F(ASessionBusConnection, ClosesAndUnrefsBusWhenDestructed)
|
||||
{
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_flush_close_unref(_)).Times(1);
|
||||
Connection(std::move(sdBusIntfMock_), session_bus);
|
||||
Connection(std::move(sdBusIntfMock_), Connection::session_bus);
|
||||
}
|
||||
|
||||
TEST_F(ADefaultBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)
|
||||
{
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1)));
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), default_bus), sdbus::Error);
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::default_bus), sdbus::Error);
|
||||
}
|
||||
|
||||
TEST_F(ASystemBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)
|
||||
{
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1)));
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), system_bus), sdbus::Error);
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::system_bus), sdbus::Error);
|
||||
}
|
||||
|
||||
TEST_F(ASessionBusConnection, ThrowsErrorWhenOpeningTheBusFailsDuringConstruction)
|
||||
{
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(-1)));
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), session_bus), sdbus::Error);
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::session_bus), sdbus::Error);
|
||||
}
|
||||
|
||||
TEST_F(ADefaultBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)
|
||||
{
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_open(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1));
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), default_bus), sdbus::Error);
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::default_bus), sdbus::Error);
|
||||
}
|
||||
|
||||
TEST_F(ASystemBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)
|
||||
{
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_open_system(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1));
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), system_bus), sdbus::Error);
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::system_bus), sdbus::Error);
|
||||
}
|
||||
|
||||
TEST_F(ASessionBusConnection, ThrowsErrorWhenFlushingTheBusFailsDuringConstruction)
|
||||
{
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillByDefault(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
ON_CALL(*sdBusIntfMock_, sd_bus_flush(_)).WillByDefault(Return(-1));
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), session_bus), sdbus::Error);
|
||||
ASSERT_THROW(Connection(std::move(sdBusIntfMock_), Connection::session_bus), sdbus::Error);
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -169,24 +165,40 @@ template<> void AConnectionNameRequest<Connection::session_bus_t>::setUpBusOpenE
|
||||
{
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_user(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
}
|
||||
template<> void AConnectionNameRequest<Connection::custom_session_bus_t>::setUpBusOpenExpectation()
|
||||
{
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_user_with_address(_, _)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
}
|
||||
template<> void AConnectionNameRequest<Connection::remote_system_bus_t>::setUpBusOpenExpectation()
|
||||
{
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_open_system_remote(_, _)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
}
|
||||
template<> void AConnectionNameRequest<Connection::pseudo_bus_t>::setUpBusOpenExpectation()
|
||||
{
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_new(_)).WillOnce(DoAll(SetArgPointee<0>(fakeBusPtr_), Return(1)));
|
||||
// `sd_bus_start` for pseudo connection shall return an error value, remember this is a fake connection...
|
||||
EXPECT_CALL(*sdBusIntfMock_, sd_bus_start(fakeBusPtr_)).WillOnce(Return(-EINVAL));
|
||||
}
|
||||
template <typename _BusTypeTag>
|
||||
std::unique_ptr<Connection> AConnectionNameRequest<_BusTypeTag>::makeConnection()
|
||||
{
|
||||
return std::make_unique<Connection>(std::unique_ptr<NiceMock<SdBusMock>>(sdBusIntfMock_), _BusTypeTag{});
|
||||
}
|
||||
template<> std::unique_ptr<Connection> AConnectionNameRequest<Connection::custom_session_bus_t>::makeConnection()
|
||||
{
|
||||
return std::make_unique<Connection>(std::unique_ptr<NiceMock<SdBusMock>>(sdBusIntfMock_), Connection::custom_session_bus, "custom session bus");
|
||||
}
|
||||
template<> std::unique_ptr<Connection> AConnectionNameRequest<Connection::remote_system_bus_t>::makeConnection()
|
||||
{
|
||||
return std::make_unique<Connection>(std::unique_ptr<NiceMock<SdBusMock>>(sdBusIntfMock_), remote_system_bus, "some host");
|
||||
return std::make_unique<Connection>(std::unique_ptr<NiceMock<SdBusMock>>(sdBusIntfMock_), Connection::remote_system_bus, "some host");
|
||||
}
|
||||
|
||||
typedef ::testing::Types< Connection::default_bus_t
|
||||
, Connection::system_bus_t
|
||||
, Connection::session_bus_t
|
||||
, Connection::custom_session_bus_t
|
||||
, Connection::remote_system_bus_t
|
||||
, Connection::pseudo_bus_t
|
||||
> BusTypeTags;
|
||||
|
||||
TYPED_TEST_SUITE(AConnectionNameRequest, BusTypeTags);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Message_test.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file TypeTraits_test.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file Types_test.cpp
|
||||
*
|
||||
@ -230,6 +230,15 @@ TEST(AnObjectPath, CanBeConstructedFromStdString)
|
||||
ASSERT_THAT(sdbus::ObjectPath{aPath}, Eq(aPath));
|
||||
}
|
||||
|
||||
TEST(AnObjectPath, CanBeMovedLikeAStdString)
|
||||
{
|
||||
std::string aPath{"/some/very/long/path/longer/than/sso"};
|
||||
sdbus::ObjectPath oPath{aPath};
|
||||
|
||||
ASSERT_THAT(sdbus::ObjectPath{std::move(oPath)}, Eq(sdbus::ObjectPath(std::move(aPath))));
|
||||
ASSERT_THAT(std::string(oPath), Eq(aPath));
|
||||
}
|
||||
|
||||
TEST(ASignature, CanBeConstructedFromCString)
|
||||
{
|
||||
const char* aSignature = "us";
|
||||
@ -244,6 +253,15 @@ TEST(ASignature, CanBeConstructedFromStdString)
|
||||
ASSERT_THAT(sdbus::Signature{aSignature}, Eq(aSignature));
|
||||
}
|
||||
|
||||
TEST(ASignature, CanBeMovedLikeAStdString)
|
||||
{
|
||||
std::string aSignature{"us"};
|
||||
sdbus::Signature oSignature{aSignature};
|
||||
|
||||
ASSERT_THAT(sdbus::Signature{std::move(oSignature)}, Eq(sdbus::Signature(std::move(aSignature))));
|
||||
ASSERT_THAT(std::string(oSignature), Eq(aSignature));
|
||||
}
|
||||
|
||||
TEST(AUnixFd, DuplicatesAndOwnsFdUponStandardConstruction)
|
||||
{
|
||||
auto fd = ::eventfd(0, EFD_SEMAPHORE | EFD_NONBLOCK);
|
||||
@ -344,3 +362,21 @@ TEST(AUnixFd, TakesOverNewFdAndClosesOriginalFdOnAdoptingReset)
|
||||
EXPECT_THAT(unixFd.get(), Eq(newFd));
|
||||
EXPECT_THAT(::close(fd), Eq(-1));
|
||||
}
|
||||
|
||||
TEST(AnError, CanBeConstructedFromANameAndAMessage)
|
||||
{
|
||||
auto error = sdbus::Error("name", "message");
|
||||
EXPECT_THAT(error.getName(), Eq<std::string>("name"));
|
||||
EXPECT_THAT(error.getMessage(), Eq<std::string>("message"));
|
||||
}
|
||||
|
||||
TEST(AnError, CanBeConstructedFromANameOnly)
|
||||
{
|
||||
auto error1 = sdbus::Error("name");
|
||||
auto error2 = sdbus::Error("name", nullptr);
|
||||
EXPECT_THAT(error1.getName(), Eq<std::string>("name"));
|
||||
EXPECT_THAT(error2.getName(), Eq<std::string>("name"));
|
||||
|
||||
EXPECT_THAT(error1.getMessage(), Eq<std::string>(""));
|
||||
EXPECT_THAT(error2.getMessage(), Eq<std::string>(""));
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file SdBusMock.h
|
||||
* @author Ardazishvili Roman (ardazishvili.roman@yandex.ru)
|
||||
@ -58,8 +58,9 @@ public:
|
||||
MOCK_METHOD3(sd_bus_emit_interfaces_removed_strv, int(sd_bus *bus, const char *path, char **interfaces));
|
||||
|
||||
MOCK_METHOD1(sd_bus_open, int(sd_bus **ret));
|
||||
MOCK_METHOD1(sd_bus_open_user, int(sd_bus **ret));
|
||||
MOCK_METHOD1(sd_bus_open_system, int(sd_bus **ret));
|
||||
MOCK_METHOD1(sd_bus_open_user, int(sd_bus **ret));
|
||||
MOCK_METHOD2(sd_bus_open_user_with_address, int(sd_bus **ret, const char* address));
|
||||
MOCK_METHOD2(sd_bus_open_system_remote, int(sd_bus **ret, const char *host));
|
||||
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));
|
||||
@ -69,11 +70,15 @@ public:
|
||||
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));
|
||||
|
||||
MOCK_METHOD1(sd_bus_new, int(sd_bus **ret));
|
||||
MOCK_METHOD1(sd_bus_start, int(sd_bus *bus));
|
||||
|
||||
MOCK_METHOD2(sd_bus_process, int(sd_bus *bus, sd_bus_message **r));
|
||||
MOCK_METHOD2(sd_bus_get_poll_data, int(sd_bus *bus, PollData* data));
|
||||
|
||||
MOCK_METHOD1(sd_bus_flush, int(sd_bus *bus));
|
||||
MOCK_METHOD1(sd_bus_flush_close_unref, sd_bus *(sd_bus *bus));
|
||||
MOCK_METHOD1(sd_bus_close_unref, sd_bus *(sd_bus *bus));
|
||||
|
||||
MOCK_METHOD2(sd_bus_message_set_destination, int(sd_bus_message *m, const char *destination));
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file sdbus-c++-unit-tests.cpp
|
||||
*
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(sdbus-c++-tools VERSION 1.1.0)
|
||||
project(sdbus-c++-tools VERSION 1.2.0)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file AdaptorGenerator.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file AdaptorGenerator.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file BaseGenerator.cpp
|
||||
*
|
||||
@ -182,4 +182,3 @@ std::string BaseGenerator::outArgsToType(const Nodes& args, bool bareList) const
|
||||
|
||||
return retTypeSS.str();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file BaseGenerator.h
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file ProxyGenerator.cpp
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file ProxyGenerator.h
|
||||
*
|
||||
|
@ -85,6 +85,15 @@ static void _parse_signature(const std::string &signature, std::string &type, un
|
||||
|
||||
break;
|
||||
}
|
||||
case '\0':
|
||||
{
|
||||
std::cerr <<
|
||||
"Invalid array definition. Type is missing after '" << signature
|
||||
<< "'."
|
||||
<< std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
type += "std::vector<";
|
||||
|
@ -292,12 +292,12 @@ void Document::Expat::character_data_handler(void* data, const XML_Char* chars,
|
||||
nod = &(nod->children.back());
|
||||
}
|
||||
|
||||
int x = 0, y = len - 1;
|
||||
int offset = 0, count = len;
|
||||
|
||||
while (isspace(chars[y]) && y > 0) --y;
|
||||
while (isspace(chars[x]) && x < y) ++x;
|
||||
while (count > 0 && isspace(chars[count - 1])) --count;
|
||||
while (offset < count && isspace(chars[offset])) { ++offset; --count; }
|
||||
|
||||
nod->cdata = std::string(chars, x, y + 1);
|
||||
nod->cdata = std::string{chars + offset, static_cast<std::string::size_type>(count)};
|
||||
}
|
||||
|
||||
void Document::Expat::end_element_handler(void* data, const XML_Char* /*name*/)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* (C) 2016 - 2017 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2019 Stanislav Angelovic <angelovic.s@gmail.com>
|
||||
* (C) 2016 - 2021 KISTLER INSTRUMENTE AG, Winterthur, Switzerland
|
||||
* (C) 2016 - 2022 Stanislav Angelovic <stanislav.angelovic@protonmail.com>
|
||||
*
|
||||
* @file xml2cpp.cpp
|
||||
*
|
||||
|
Reference in New Issue
Block a user