blob: a96d5ac1432eb12287820c7b4ad9db336e4173be [file] [log] [blame]
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2020 YADRO
#pragma once
#include <systemd/sd-bus.h>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <vector>
/**
* @class DbusLoop
* @brief D-Bus based event loop.
*/
class DbusLoop
{
public:
/** @brief Set of possible values of the property. */
using PropertyValues = std::set<std::string>;
/** @brief Map of properties: name -> watched values. */
using Properties = std::map<std::string, PropertyValues>;
/** @brief Map of watched properties: interface -> properties. */
using WatchProperties = std::map<std::string, Properties>;
DbusLoop();
virtual ~DbusLoop();
/**
* @brief Run worker loop.
*
* @return exit code from loop
*/
virtual int run() const;
/**
* @brief Stop worker loop.
*
* @param[in] code exit code
*/
void stop(int code) const;
/**
* @brief Add property change handler.
*
* @param[in] service D-Bus service name (object owner)
* @param[in] objPath path to the D-Bus object
* @param[in] props watched properties description
* @param[in] callback function to call when property get one the listed
* values
*
* @throw std::system_error in case of errors
*/
virtual void addPropertyHandler(const std::string& objPath,
const WatchProperties& props,
std::function<void()> callback);
/**
* @brief Add IO event handler.
*
* @param[in] fd file descriptor to watch
* @param[in] callback function to call when IO event is occurred
*
* @throw std::system_error in case of errors
*/
virtual void addIoHandler(int fd, std::function<void()> callback);
/**
* @brief Add signal handler.
*
* @param[in] signal signal to watch
* @param[in] callback function to call when signal is triggered
*
* @throw std::system_error in case of errors
*/
virtual void addSignalHandler(int signal, std::function<void()> callback);
private:
/**
* @brief D-Bus callback: message handler.
* See sd_bus_message_handler_t for details.
*/
static int msgCallback(sd_bus_message* msg, void* userdata,
sd_bus_error* err);
/**
* @brief D-Bus callback: signal handler.
* See sd_event_signal_handler_t for details.
*/
static int signalCallback(sd_event_source* src,
const struct signalfd_siginfo* si,
void* userdata);
/**
* @brief D-Bus callback: IO handler.
* See sd_event_io_handler_t for details.
*/
static int ioCallback(sd_event_source* src, int fd, uint32_t revents,
void* userdata);
private:
/** @brief D-Bus connection. */
sd_bus* bus;
/** @brief D-Bus event loop. */
sd_event* event;
/** @brief Watched properties. */
WatchProperties propWatch;
/** @brief Property change handler. */
std::function<void()> propHandler;
/** @brief IO handler. */
std::function<void()> ioHandler;
/** @brief Signal handlers. */
std::map<int, std::function<void()>> signalHandlers;
};