blob: 84f45ce829611daf50fc2a091c98275ec198a726 [file] [log] [blame]
Patrick Williams5b485792016-08-02 07:35:14 -05001#pragma once
2
3#include <memory>
Brad Bishop887ebf62016-10-12 15:40:04 -04004#include <climits>
Patrick Williams5b485792016-08-02 07:35:14 -05005#include <systemd/sd-bus.h>
Patrick Williams7802c072016-09-02 15:20:22 -05006#include <sdbusplus/message.hpp>
Patrick Williams5b485792016-08-02 07:35:14 -05007
8namespace sdbusplus
9{
Patrick Williams13f1ef72016-10-17 14:09:33 -050010
11// Forward declare.
12namespace server { namespace interface { struct interface; } }
Patrick Williams05aab8b2016-10-17 14:12:12 -050013namespace server { namespace manager { struct manager; } }
Patrick Williamsd1102f42016-10-17 21:42:38 -050014namespace server { namespace object { template<class...> struct object; } }
Patrick Williams13f1ef72016-10-17 14:09:33 -050015
Patrick Williams5b485792016-08-02 07:35:14 -050016namespace bus
17{
18
19using busp_t = sd_bus*;
20class bus;
21
22/** @brief Get an instance of the 'default' bus. */
23bus new_default();
24/** @brief Get an instance of the 'user' session bus. */
25bus new_user();
26/** @brief Get an instance of the 'system' bus. */
27bus new_system();
28
29namespace details
30{
31
32/** @brief unique_ptr functor to release a bus reference. */
33struct BusDeleter
34{
35 void operator()(sd_bus* ptr) const
36 {
Patrick Williams67df0f22016-10-16 17:58:03 -050037 sd_bus_unref(ptr);
Patrick Williams5b485792016-08-02 07:35:14 -050038 }
39};
40
41/* @brief Alias 'bus' to a unique_ptr type for auto-release. */
42using bus = std::unique_ptr<sd_bus, BusDeleter>;
43
44} // namespace details
45
46/** @class bus
47 * @brief Provides C++ bindings to the sd_bus_* class functions.
48 */
49struct bus
50{
51 /* Define all of the basic class operations:
52 * Not allowed:
53 * - Default constructor to avoid nullptrs.
54 * - Copy operations due to internal unique_ptr.
55 * Allowed:
56 * - Move operations.
57 * - Destructor.
58 */
59 bus() = delete;
60 bus(const bus&) = delete;
61 bus& operator=(const bus&) = delete;
62 bus(bus&&) = default;
63 bus& operator=(bus&&) = default;
64 ~bus() = default;
65
66 /** @brief Conversion constructor from 'busp_t'.
67 *
68 * Takes ownership of the bus-pointer and releases it when done.
69 */
70 explicit bus(busp_t b) : _bus(b) {}
71
72 /** @brief Release ownership of the stored bus-pointer. */
73 busp_t release() { return _bus.release(); }
74
75 /** @brief Wait for new dbus messages or signals.
76 *
77 * @param[in] timeout_us - Timeout in usec.
78 */
Brad Bishop887ebf62016-10-12 15:40:04 -040079 void wait(uint64_t timeout_us = ULLONG_MAX)
Patrick Williams5b485792016-08-02 07:35:14 -050080 {
81 sd_bus_wait(_bus.get(), timeout_us);
82 }
83
84 /** @brief Process waiting dbus messages or signals. */
85 auto process()
86 {
87 sd_bus_message* m = nullptr;
88 sd_bus_process(_bus.get(), &m);
89
Patrick Williams13b97c52016-09-09 09:36:55 -050090 return message::message(m);
Patrick Williams5b485792016-08-02 07:35:14 -050091 }
92
Patrick Williamsc7ba66f2016-10-18 11:30:07 -050093 /** @brief Process waiting dbus messages or signals, discarding unhandled.
94 */
95 void process_discard()
96 {
97 sd_bus_process(_bus.get(), nullptr);
98 }
99
Patrick Williams5b485792016-08-02 07:35:14 -0500100 /** @brief Claim a service name on the dbus.
101 *
102 * @param[in] service - The service name to claim.
103 */
104 void request_name(const char* service)
105 {
106 sd_bus_request_name(_bus.get(), service, 0);
107 }
108
109 /** @brief Create a method_call message.
110 *
111 * @param[in] service - The service to call.
112 * @param[in] objpath - The object's path for the call.
113 * @param[in] interf - The object's interface to call.
114 * @param[in] method - The object's method to call.
115 *
116 * @return A newly constructed message.
117 */
118 auto new_method_call(const char* service, const char* objpath,
119 const char* interf, const char* method)
120 {
121 sd_bus_message* m = nullptr;
122 sd_bus_message_new_method_call(_bus.get(), &m, service, objpath,
123 interf, method);
124
Patrick Williams7802c072016-09-02 15:20:22 -0500125 return message::message(m);
Patrick Williams5b485792016-08-02 07:35:14 -0500126 }
127
Patrick Williams20d82462016-10-18 08:01:33 -0500128 /** @brief Create a signal message.
129 *
130 * @param[in] objpath - The object's path for the signal.
131 * @param[in] interf - The object's interface for the signal.
132 * @param[in] member - The signal name.
133 *
134 * @return A newly constructed message.
135 */
136 auto new_signal(const char* objpath, const char* interf, const char* member)
137 {
138 sd_bus_message* m = nullptr;
139 sd_bus_message_new_signal(_bus.get(), &m, objpath, interf, member);
140
141 return message::message(m);
142 }
143
Patrick Williams5b485792016-08-02 07:35:14 -0500144 /** @brief Perform a message call.
145 *
146 * @param[in] m - The method_call message.
147 * @param[in] timeout_us - The timeout for the method call.
148 *
149 * @return The response message.
150 */
Patrick Williams7802c072016-09-02 15:20:22 -0500151 auto call(message::message& m, uint64_t timeout_us = 0)
Patrick Williams5b485792016-08-02 07:35:14 -0500152 {
153 sd_bus_message* reply = nullptr;
Patrick Williams7802c072016-09-02 15:20:22 -0500154 sd_bus_call(_bus.get(), m.get(), timeout_us, nullptr, &reply);
Patrick Williams5b485792016-08-02 07:35:14 -0500155
156 return reply;
157 }
158
159 /** @brief Perform a message call, ignoring the reply.
160 *
161 * @param[in] m - The method_call message.
162 * @param[in] timeout_us - The timeout for the method call.
163 */
Patrick Williams7802c072016-09-02 15:20:22 -0500164 void call_noreply(message::message& m, uint64_t timeout_us = 0)
Patrick Williams5b485792016-08-02 07:35:14 -0500165 {
Patrick Williams7802c072016-09-02 15:20:22 -0500166 sd_bus_call(_bus.get(), m.get(), timeout_us, nullptr, nullptr);
Patrick Williams5b485792016-08-02 07:35:14 -0500167 }
168
Patrick Williams13f1ef72016-10-17 14:09:33 -0500169 friend struct server::interface::interface;
Patrick Williams05aab8b2016-10-17 14:12:12 -0500170 friend struct server::manager::manager;
Patrick Williamsd1102f42016-10-17 21:42:38 -0500171 template<class... Args> friend struct server::object::object;
Patrick Williams13f1ef72016-10-17 14:09:33 -0500172
Patrick Williams5b485792016-08-02 07:35:14 -0500173 private:
Patrick Williams13f1ef72016-10-17 14:09:33 -0500174 busp_t get() { return _bus.get(); }
Patrick Williams5b485792016-08-02 07:35:14 -0500175 details::bus _bus;
176};
177
Brad Bishopaed81792016-10-12 08:40:34 -0400178inline bus new_default()
Patrick Williams5b485792016-08-02 07:35:14 -0500179{
180 sd_bus* b = nullptr;
181 sd_bus_open(&b);
182 return bus(b);
183}
184
Brad Bishopaed81792016-10-12 08:40:34 -0400185inline bus new_user()
Patrick Williams5b485792016-08-02 07:35:14 -0500186{
187 sd_bus* b = nullptr;
188 sd_bus_open_user(&b);
189 return bus(b);
190}
191
Brad Bishopaed81792016-10-12 08:40:34 -0400192inline bus new_system()
Patrick Williams5b485792016-08-02 07:35:14 -0500193{
194 sd_bus* b = nullptr;
195 sd_bus_open_system(&b);
196 return bus(b);
197}
198
Patrick Williams5b485792016-08-02 07:35:14 -0500199} // namespace bus
200
201} // namespace sdbusplus