Skip to content

Commit

Permalink
Implement DBus server using glib
Browse files Browse the repository at this point in the history
To remove third-party dbus lib dependency, use glib high API to handle
DBus server. DBusServer.cpp uses "C" stubs generated by gdbus-codege
(DBusControl.c, DBusControl.h).

Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Reviewed-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Tested-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
  • Loading branch information
al1img authored and andr2000 committed May 25, 2020
1 parent ca28149 commit 868e703
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 190 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,13 @@ DisplayManager -c display.cfg -v *:Debug
Getting introspect:

```bash
dbus-send --session --print-reply --dest=com.epam.DisplayManager /com/epam/DisplayManager org.freedesktop.DBus.Introspectable.Introspect
dbus-send --system --print-reply --dest=com.epam.DisplayManager /com/epam/DisplayManager org.freedesktop.DBus.Introspectable.Introspect
```

Sending user event `1`:

```bash
dbus-send --session --dest=com.epam.DisplayManager --type=method_call /com/epam/DisplayManager com.epam.DisplayManager.Control.userEvent uint32:1
```
dbus-send --system --dest=com.epam.DisplayManager --type=method_call /com/epam/DisplayManager com.epam.DisplayManager.Control.userEvent uint32:1
```

If DisplayManager is launched in session DBus mode, use `--session` instead of `--system`.
28 changes: 23 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ if(NOT ILM_COMMON_FOUND)
set(ILM_COMMON_LIBRARIES ilmCommon)
endif()

pkg_check_modules(DBUS_CXX REQUIRED dbus-cxx-1.0)
pkg_check_modules(GLIB REQUIRED glib-2.0)
pkg_check_modules(GIO REQUIRED gio-unix-2.0)

find_program(GDBUS_CODEGEN NAMES gdbus-codegen)
if (NOT GDBUS_CODEGEN)
message(SEND_ERROR "Can't find gdbus-codegen")
endif()

################################################################################
# CFLAGS
Expand All @@ -28,13 +34,24 @@ pkg_check_modules(DBUS_CXX REQUIRED dbus-cxx-1.0)

include_directories(
.
${CMAKE_CURRENT_BINARY_DIR}
${CONFIG_INCLUDE_DIRS}
${DBUS_CXX_INCLUDE_DIRS}
${GLIB_INCLUDE_DIRS}
${GIO_INCLUDE_DIRS}
${ILM_CTRL_INCLUDE_DIRS}
${ILM_COMMON_INCLUDE_DIRS}
)

message(STATUS "DBUS_CXX_INCLUDE_DIRS = ${DBUS_CXX_INCLUDE_DIRS}")
message(STATUS "GIO_INCLUDE_DIRS = ${GIO_INCLUDE_DIRS}")

################################################################################
# DBus stubs
################################################################################

add_custom_command(OUTPUT DBusControl.c
COMMAND ${GDBUS_CODEGEN} --interface-prefix com.epam.DisplayManager. --generate-c-code=DBusControl ${PROJECT_SOURCE_DIR}/src/com.epam.displaymanager.xml
DEPENDS ${PROJECT_SOURCE_DIR}/src/com.epam.displaymanager.xml
)

################################################################################
# Sources
Expand All @@ -44,7 +61,7 @@ set(SOURCES
main.cpp
ActionManager.cpp
Config.cpp
DBusControlAdapter.cpp
DBusControl.c
DBusServer.cpp
Display.cpp
DisplayManager.cpp
Expand All @@ -71,7 +88,8 @@ install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
target_link_libraries(${PROJECT_NAME}
pthread
${CONFIG_LIBRARIES}
${DBUS_CXX_LIBRARIES}
${GLIB_LIBRARIES}
${GIO_LIBRARIES}
${ILM_CTRL_LIBRARIES}
${ILM_COMMON_LIBRARIES}
)
31 changes: 0 additions & 31 deletions src/DBusControlAdaptee.hpp

This file was deleted.

48 changes: 0 additions & 48 deletions src/DBusControlAdapter.cpp

This file was deleted.

43 changes: 0 additions & 43 deletions src/DBusControlAdapter.hpp

This file was deleted.

124 changes: 85 additions & 39 deletions src/DBusServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,63 +20,109 @@

#include "DBusServer.hpp"

#include "ActionManager.hpp"
#include <glib-unix.h>

using DBus::BUS_SESSION;
using DBus::BUS_SYSTEM;
using DBus::Dispatcher;
using DBus::init;
#include "ActionManager.hpp"

using std::exception;
using std::runtime_error;
using std::shared_ptr;
/*******************************************************************************
* Static
******************************************************************************/

DBusServer::DBusServer(ActionManager& actions, bool systemBus)
: mActions(actions), mLog("DBusServer")
namespace {
gboolean sTerminationHandler(gpointer data)
{
LOG(mLog, DEBUG) << "Create";
LOG("main", INFO) << "Terminating...";

try {
init();
g_main_loop_quit(reinterpret_cast<GMainLoop*>(data));

mDispatcher = Dispatcher::create();
return false;
}
} // namespace

if (systemBus) {
mConnection = mDispatcher->create_connection(BUS_SYSTEM);
}
else {
mConnection = mDispatcher->create_connection(BUS_SESSION);
}
/*******************************************************************************
* DBusServer
******************************************************************************/

if (mConnection->request_name("com.epam.DisplayManager",
DBUS_NAME_FLAG_REPLACE_EXISTING) !=
DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
throw(runtime_error("Can't request DBus name"));
}
DBusServer::DBusServer(ActionManager& actions, bool systemBus)
: mActions(actions), mLoop(nullptr), mLog("DBusServer")
{
LOG(mLog, DEBUG) << "Create " << (systemBus ? "system" : "session")
<< " bus";

DBusControlAdapter::create(this);
mLoop = g_main_loop_new(NULL, FALSE);

mAdapter = DBusControlAdapter::create(this);
mConnection->register_object(mAdapter);
}
catch (const std::shared_ptr<DBus::Error> e) {
throw DmException(e->what());
}
g_unix_signal_add(SIGINT, sTerminationHandler, mLoop);
g_unix_signal_add(SIGTERM, sTerminationHandler, mLoop);

mBusId = g_bus_own_name(
(systemBus ? G_BUS_TYPE_SYSTEM : G_BUS_TYPE_SESSION), sBusName,
static_cast<GBusNameOwnerFlags>(
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
G_BUS_NAME_OWNER_FLAGS_REPLACE),
DBusServer::sOnBusAcquired, nullptr, nullptr, this, nullptr);
}

DBusServer::~DBusServer()
{
LOG(mLog, DEBUG) << "Delete";

g_bus_unown_name(mBusId);
g_main_loop_unref(mLoop);
}

void DBusServer::userEvent(uint32_t event)
/*******************************************************************************
* Public
******************************************************************************/

void DBusServer::run()
{
try {
LOG(mLog, DEBUG) << "User event: " << event;
g_main_loop_run(mLoop);
}

mActions.userEvent(event);
}
catch (const exception& e) {
LOG(mLog, ERROR) << e.what();
/*******************************************************************************
* Private
******************************************************************************/

void DBusServer::sOnBusAcquired(GDBusConnection* connection, const gchar* name,
gpointer userData)
{
static_cast<DBusServer*>(userData)->onBusAcquired(connection, name);
}

void DBusServer::onBusAcquired(GDBusConnection* connection, const gchar* name)
{
LOG(mLog, DEBUG) << "Bus acquired, name: " << name;

auto interface = control_skeleton_new();

g_signal_connect(interface, "handle-user-event",
G_CALLBACK(DBusServer::sHandleUserEvent), this);

GError* error = nullptr;

if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(interface),
connection, sObjectPath, &error)) {
LOG(mLog, ERROR) << "Can't export interface: " << error->message;

g_main_loop_quit(mLoop);
}
}

bool DBusServer::sHandleUserEvent(Control* interface,
GDBusMethodInvocation* invocation,
guint userEvent, gpointer userData)
{
return static_cast<DBusServer*>(userData)->handleUserEvent(
interface, invocation, userEvent);
}

bool DBusServer::handleUserEvent(Control* interface,
GDBusMethodInvocation* invocation,
guint userEvent)
{
LOG(mLog, DEBUG) << "User event received: " << userEvent;

mActions.userEvent(userEvent);

return false;
}
Loading

0 comments on commit 868e703

Please sign in to comment.