blob: a96d5ac1432eb12287820c7b4ad9db336e4173be [file] [log] [blame]
Artem Senicheve8837d52020-06-07 11:59:04 +03001// SPDX-License-Identifier: Apache-2.0
2// Copyright (C) 2020 YADRO
3
4#pragma once
5
6#include <systemd/sd-bus.h>
7
8#include <functional>
9#include <map>
10#include <set>
11#include <string>
12#include <vector>
13
14/**
15 * @class DbusLoop
16 * @brief D-Bus based event loop.
17 */
18class DbusLoop
19{
20 public:
21 /** @brief Set of possible values of the property. */
22 using PropertyValues = std::set<std::string>;
23 /** @brief Map of properties: name -> watched values. */
24 using Properties = std::map<std::string, PropertyValues>;
25 /** @brief Map of watched properties: interface -> properties. */
26 using WatchProperties = std::map<std::string, Properties>;
27
28 DbusLoop();
Nan Zhou042b5ba2021-06-18 09:32:45 -070029 virtual ~DbusLoop();
Artem Senicheve8837d52020-06-07 11:59:04 +030030
31 /**
32 * @brief Run worker loop.
33 *
34 * @return exit code from loop
35 */
Nan Zhou042b5ba2021-06-18 09:32:45 -070036 virtual int run() const;
Artem Senicheve8837d52020-06-07 11:59:04 +030037
38 /**
39 * @brief Stop worker loop.
40 *
41 * @param[in] code exit code
42 */
43 void stop(int code) const;
44
45 /**
46 * @brief Add property change handler.
47 *
48 * @param[in] service D-Bus service name (object owner)
49 * @param[in] objPath path to the D-Bus object
50 * @param[in] props watched properties description
51 * @param[in] callback function to call when property get one the listed
52 * values
53 *
54 * @throw std::system_error in case of errors
55 */
Nan Zhou042b5ba2021-06-18 09:32:45 -070056 virtual void addPropertyHandler(const std::string& objPath,
57 const WatchProperties& props,
58 std::function<void()> callback);
Artem Senicheve8837d52020-06-07 11:59:04 +030059
60 /**
61 * @brief Add IO event handler.
62 *
63 * @param[in] fd file descriptor to watch
64 * @param[in] callback function to call when IO event is occurred
65 *
66 * @throw std::system_error in case of errors
67 */
Nan Zhou042b5ba2021-06-18 09:32:45 -070068 virtual void addIoHandler(int fd, std::function<void()> callback);
Artem Senicheve8837d52020-06-07 11:59:04 +030069
70 /**
71 * @brief Add signal handler.
72 *
73 * @param[in] signal signal to watch
74 * @param[in] callback function to call when signal is triggered
75 *
76 * @throw std::system_error in case of errors
77 */
Nan Zhou042b5ba2021-06-18 09:32:45 -070078 virtual void addSignalHandler(int signal, std::function<void()> callback);
Artem Senicheve8837d52020-06-07 11:59:04 +030079
80 private:
81 /**
82 * @brief D-Bus callback: message handler.
83 * See sd_bus_message_handler_t for details.
84 */
85 static int msgCallback(sd_bus_message* msg, void* userdata,
86 sd_bus_error* err);
87
88 /**
89 * @brief D-Bus callback: signal handler.
90 * See sd_event_signal_handler_t for details.
91 */
92 static int signalCallback(sd_event_source* src,
93 const struct signalfd_siginfo* si,
94 void* userdata);
95
96 /**
97 * @brief D-Bus callback: IO handler.
98 * See sd_event_io_handler_t for details.
99 */
100 static int ioCallback(sd_event_source* src, int fd, uint32_t revents,
101 void* userdata);
102
103 private:
104 /** @brief D-Bus connection. */
105 sd_bus* bus;
106 /** @brief D-Bus event loop. */
107 sd_event* event;
108
109 /** @brief Watched properties. */
110 WatchProperties propWatch;
111 /** @brief Property change handler. */
112 std::function<void()> propHandler;
113
114 /** @brief IO handler. */
115 std::function<void()> ioHandler;
116
117 /** @brief Signal handlers. */
118 std::map<int, std::function<void()>> signalHandlers;
119};