blob: 697804dfb729ba2ded7bc74cadc02f9171f7052c [file] [log] [blame]
Patrick Williams5b485792016-08-02 07:35:14 -05001#pragma once
2
Brad Bishopb4cc7d72018-12-06 15:27:48 -05003#include <systemd/sd-bus.h>
4#include <systemd/sd-event.h>
5
Patrick Williams127b8ab2020-05-21 15:24:19 -05006#include <sdbusplus/exception.hpp>
7#include <sdbusplus/message.hpp>
8#include <sdbusplus/sdbus.hpp>
9
Brad Bishopd2945572017-02-15 23:40:15 -050010#include <algorithm>
Brad Bishop887ebf62016-10-12 15:40:04 -040011#include <climits>
Hannu Lounento90f8d9b2023-03-13 11:05:08 +020012#include <exception>
Patrick Venture2ea15b72018-06-22 08:41:18 -070013#include <memory>
William A. Kennington IIIb5a84462019-03-06 16:46:57 -080014#include <optional>
Patrick Venture2ea15b72018-06-22 08:41:18 -070015#include <string>
Patrick Venture2ea15b72018-06-22 08:41:18 -070016#include <vector>
Patrick Ventureff095682018-04-13 20:54:32 -070017
Patrick Williams0c8136a2021-08-28 14:42:31 -050018#ifdef __clang__
19#pragma clang diagnostic push
20#pragma clang diagnostic ignored "-Wc99-extensions"
21#endif
22
Patrick Williams5b485792016-08-02 07:35:14 -050023namespace sdbusplus
24{
Patrick Williams13f1ef72016-10-17 14:09:33 -050025
Patrick Williams5b485792016-08-02 07:35:14 -050026namespace bus
27{
28
29using busp_t = sd_bus*;
Ed Tanous8cd7a4a2019-03-13 16:41:49 -070030struct bus;
Patrick Williams5b485792016-08-02 07:35:14 -050031
32/** @brief Get an instance of the 'default' bus. */
33bus new_default();
34/** @brief Get an instance of the 'user' session bus. */
35bus new_user();
36/** @brief Get an instance of the 'system' bus. */
37bus new_system();
38
39namespace details
40{
41
42/** @brief unique_ptr functor to release a bus reference. */
43struct BusDeleter
44{
Brad Bishop75834602018-12-11 08:42:53 -050045 BusDeleter() = delete;
Patrick Williamsf289c652022-08-26 10:43:10 -050046 explicit BusDeleter(SdBusInterface* interface) : m_interface(interface) {}
Patrick Williamsba6f50c2017-04-18 11:38:30 -050047
Brad Bishop75834602018-12-11 08:42:53 -050048 void operator()(sd_bus* ptr) const
49 {
50 (m_interface->*deleter)(ptr);
51 }
52
53 SdBusInterface* m_interface;
William A. Kennington III062205d2018-12-19 17:34:13 -080054 decltype(&SdBusInterface::sd_bus_unref) deleter =
55 &SdBusInterface::sd_bus_unref;
Patrick Williams5b485792016-08-02 07:35:14 -050056};
57
Brad Bishopd2945572017-02-15 23:40:15 -050058/** @brief Convert a vector of strings to c-style char** array. */
59class Strv
60{
Brad Bishopb4cc7d72018-12-06 15:27:48 -050061 public:
62 ~Strv() = default;
63 Strv() = delete;
64 Strv(const Strv&) = delete;
65 Strv& operator=(const Strv&) = delete;
66 Strv(Strv&&) = default;
67 Strv& operator=(Strv&&) = default;
Brad Bishopd2945572017-02-15 23:40:15 -050068
Brad Bishopb4cc7d72018-12-06 15:27:48 -050069 explicit Strv(const std::vector<std::string>& v)
70 {
71 std::transform(v.begin(), v.end(), std::back_inserter(ptrs),
72 [](const auto& i) { return i.c_str(); });
73 ptrs.push_back(nullptr);
74 }
Brad Bishopd2945572017-02-15 23:40:15 -050075
Patrick Williams4b646232021-02-22 13:50:48 -060076 explicit operator char**()
Brad Bishopb4cc7d72018-12-06 15:27:48 -050077 {
78 return const_cast<char**>(&ptrs.front());
79 }
Brad Bishopd2945572017-02-15 23:40:15 -050080
Brad Bishopb4cc7d72018-12-06 15:27:48 -050081 private:
82 std::vector<const char*> ptrs;
Brad Bishopd2945572017-02-15 23:40:15 -050083};
84
Patrick Williams5b485792016-08-02 07:35:14 -050085/* @brief Alias 'bus' to a unique_ptr type for auto-release. */
86using bus = std::unique_ptr<sd_bus, BusDeleter>;
87
Patrick Williams66492212021-11-19 16:49:28 -060088struct bus_friend;
89
Patrick Williams5b485792016-08-02 07:35:14 -050090} // namespace details
91
92/** @class bus
93 * @brief Provides C++ bindings to the sd_bus_* class functions.
94 */
95struct bus
96{
Patrick Ventureff095682018-04-13 20:54:32 -070097 /* Define all of the basic class operations:
98 * Not allowed:
99 * - Default constructor to avoid nullptrs.
100 * - Copy operations due to internal unique_ptr.
101 * Allowed:
102 * - Move operations.
103 * - Destructor.
104 */
Patrick Williams5b485792016-08-02 07:35:14 -0500105 bus() = delete;
106 bus(const bus&) = delete;
107 bus& operator=(const bus&) = delete;
Patrick Ventureff095682018-04-13 20:54:32 -0700108
Patrick Williams5b485792016-08-02 07:35:14 -0500109 bus(bus&&) = default;
110 bus& operator=(bus&&) = default;
111 ~bus() = default;
112
Patrick Ventureff095682018-04-13 20:54:32 -0700113 bus(busp_t b, sdbusplus::SdBusInterface* intf);
114
Patrick Williams5b485792016-08-02 07:35:14 -0500115 /** @brief Conversion constructor from 'busp_t'.
116 *
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500117 * Increments ref-count of the bus-pointer and releases it when done.
Patrick Williams5b485792016-08-02 07:35:14 -0500118 */
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600119 explicit bus(busp_t b);
Patrick Williams5b485792016-08-02 07:35:14 -0500120
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500121 /** @brief Constructor for 'bus'.
122 *
123 * Takes ownership of the bus-pointer and releases it when done.
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500124 */
125 bus(busp_t b, std::false_type);
126
William A. Kennington III062205d2018-12-19 17:34:13 -0800127 /** @brief Sets the bus to be closed when this handle is destroyed. */
128 void set_should_close(bool shouldClose)
129 {
130 if (shouldClose)
131 {
132 _bus.get_deleter().deleter =
133 &SdBusInterface::sd_bus_flush_close_unref;
134 }
135 else
136 {
137 _bus.get_deleter().deleter = &SdBusInterface::sd_bus_unref;
138 }
139 }
140
Patrick Williams5b485792016-08-02 07:35:14 -0500141 /** @brief Release ownership of the stored bus-pointer. */
Patrick Ventureff095682018-04-13 20:54:32 -0700142 busp_t release()
143 {
144 return _bus.release();
145 }
Patrick Williams5b485792016-08-02 07:35:14 -0500146
William A. Kennington III42f6ad52018-12-19 17:32:30 -0800147 /** @brief Flush all of the outstanding work on the bus. */
148 void flush()
149 {
150 int r = _intf->sd_bus_flush(_bus.get());
151 if (r < 0)
152 {
153 throw exception::SdBusError(-r, "sd_bus_flush");
154 }
155 }
156
157 /** @brief Close the connection to the dbus daemon. */
158 void close()
159 {
160 _intf->sd_bus_close(_bus.get());
161 }
162
William A. Kennington III5d81ca22022-11-22 02:28:17 -0800163 /** @brief Determine if the bus is open to the broker */
164 bool is_open()
165 {
166 int r = _intf->sd_bus_is_open(_bus.get());
167 if (r < 0)
168 {
169 throw exception::SdBusError(-r, "sd_bus_is_open");
170 }
171 return r;
172 }
173
Patrick Williams5b485792016-08-02 07:35:14 -0500174 /** @brief Wait for new dbus messages or signals.
175 *
176 * @param[in] timeout_us - Timeout in usec.
177 */
William A. Kennington III94865b32022-11-21 18:02:09 -0800178 int wait(uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500179 {
William A. Kennington III94865b32022-11-21 18:02:09 -0800180 int r = _intf->sd_bus_wait(_bus.get(), timeout_us);
181 if (r < 0)
182 {
183 throw exception::SdBusError(-r, "sd_bus_wait");
184 }
185 return r;
Patrick Williams5b485792016-08-02 07:35:14 -0500186 }
William A. Kennington III94865b32022-11-21 18:02:09 -0800187
188 int wait(std::optional<SdBusDuration> timeout = std::nullopt)
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800189 {
William A. Kennington III94865b32022-11-21 18:02:09 -0800190 return wait(timeout ? timeout->count() : UINT64_MAX);
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800191 }
Patrick Williams5b485792016-08-02 07:35:14 -0500192
193 /** @brief Process waiting dbus messages or signals. */
194 auto process()
195 {
196 sd_bus_message* m = nullptr;
William A. Kennington III49e4bdc2018-06-05 23:28:02 -0700197 int r = _intf->sd_bus_process(_bus.get(), &m);
Hannu Lounento90f8d9b2023-03-13 11:05:08 +0200198 if (current_exception)
199 {
200 auto ex = std::exchange(current_exception, nullptr);
201 std::rethrow_exception(ex);
202 }
William A. Kennington III49e4bdc2018-06-05 23:28:02 -0700203 if (r < 0)
204 {
205 throw exception::SdBusError(-r, "sd_bus_process");
206 }
Patrick Williams5b485792016-08-02 07:35:14 -0500207
Patrick Williams10d7aa12021-11-19 11:36:18 -0600208 return message_t(m, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500209 }
210
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500211 /** @brief Process waiting dbus messages or signals, discarding unhandled.
212 */
James Feistb5755182018-07-16 10:30:08 -0700213 auto process_discard()
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500214 {
William A. Kennington III49e4bdc2018-06-05 23:28:02 -0700215 int r = _intf->sd_bus_process(_bus.get(), nullptr);
Hannu Lounento90f8d9b2023-03-13 11:05:08 +0200216 if (current_exception)
217 {
218 auto ex = std::exchange(current_exception, nullptr);
219 std::rethrow_exception(ex);
220 }
William A. Kennington III49e4bdc2018-06-05 23:28:02 -0700221 if (r < 0)
222 {
223 throw exception::SdBusError(-r, "sd_bus_process discard");
224 }
James Feistb5755182018-07-16 10:30:08 -0700225 return r > 0;
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500226 }
227
Nan Zhou25e2a092022-09-01 03:47:19 +0000228 /** @brief Process waiting dbus messages or signals forever, discarding
229 * unhandled.
230 */
Brad Bishope8c76142022-09-29 11:07:00 -0400231 [[noreturn]] void process_loop()
Nan Zhou25e2a092022-09-01 03:47:19 +0000232 {
233 while (true)
234 {
235 process_discard();
236 wait();
237 }
238 }
239
Patrick Williams5b485792016-08-02 07:35:14 -0500240 /** @brief Claim a service name on the dbus.
241 *
242 * @param[in] service - The service name to claim.
243 */
244 void request_name(const char* service)
245 {
Michal Orzel946c9402023-03-29 15:51:27 +0200246 int r = _intf->sd_bus_request_name(
247 _bus.get(), service,
248 (SD_BUS_NAME_ALLOW_REPLACEMENT | SD_BUS_NAME_REPLACE_EXISTING));
Waqar Hameed841d8d32018-10-04 13:35:43 +0200249 if (r < 0)
250 {
251 throw exception::SdBusError(-r, "sd_bus_request_name");
252 }
Patrick Williams5b485792016-08-02 07:35:14 -0500253 }
254
255 /** @brief Create a method_call message.
256 *
257 * @param[in] service - The service to call.
258 * @param[in] objpath - The object's path for the call.
259 * @param[in] interf - The object's interface to call.
260 * @param[in] method - The object's method to call.
261 *
262 * @return A newly constructed message.
263 */
264 auto new_method_call(const char* service, const char* objpath,
265 const char* interf, const char* method)
266 {
267 sd_bus_message* m = nullptr;
William A. Kennington IIIec9236d2018-06-05 23:30:15 -0700268 int r = _intf->sd_bus_message_new_method_call(_bus.get(), &m, service,
269 objpath, interf, method);
270 if (r < 0)
271 {
272 throw exception::SdBusError(-r, "sd_bus_message_new_method_call");
273 }
Patrick Williams5b485792016-08-02 07:35:14 -0500274
Patrick Williams10d7aa12021-11-19 11:36:18 -0600275 return message_t(m, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500276 }
277
Patrick Williams20d82462016-10-18 08:01:33 -0500278 /** @brief Create a signal message.
279 *
280 * @param[in] objpath - The object's path for the signal.
281 * @param[in] interf - The object's interface for the signal.
282 * @param[in] member - The signal name.
283 *
284 * @return A newly constructed message.
285 */
286 auto new_signal(const char* objpath, const char* interf, const char* member)
287 {
288 sd_bus_message* m = nullptr;
William A. Kennington IIIec9236d2018-06-05 23:30:15 -0700289 int r = _intf->sd_bus_message_new_signal(_bus.get(), &m, objpath,
290 interf, member);
291 if (r < 0)
292 {
293 throw exception::SdBusError(-r, "sd_bus_message_new_signal");
294 }
Patrick Williams20d82462016-10-18 08:01:33 -0500295
Patrick Williams10d7aa12021-11-19 11:36:18 -0600296 return message_t(m, _intf, std::false_type());
Patrick Williams20d82462016-10-18 08:01:33 -0500297 }
298
Patrick Williams5b485792016-08-02 07:35:14 -0500299 /** @brief Perform a message call.
William A. Kennington III079fb852018-10-12 13:36:31 -0700300 * Errors generated by this call come from underlying dbus
301 * related errors *AND* from any method call that results
302 * in a METHOD_ERROR. This means you do not need to check
303 * is_method_error() on the returned message.
Patrick Williams5b485792016-08-02 07:35:14 -0500304 *
305 * @param[in] m - The method_call message.
306 * @param[in] timeout_us - The timeout for the method call.
307 *
308 * @return The response message.
309 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600310 auto call(message_t& m, uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500311 {
William A. Kennington III55d66862018-05-29 17:13:35 -0700312 sd_bus_error error = SD_BUS_ERROR_NULL;
Patrick Williams5b485792016-08-02 07:35:14 -0500313 sd_bus_message* reply = nullptr;
Patrick Williams1a25a102022-09-29 17:18:26 -0500314 int r = _intf->sd_bus_call(_bus.get(), m.get(), timeout_us, &error,
315 &reply);
William A. Kennington III55d66862018-05-29 17:13:35 -0700316 if (r < 0)
317 {
William A. Kennington III68cb1702018-06-22 19:35:48 -0700318 throw exception::SdBusError(&error, "sd_bus_call");
William A. Kennington III55d66862018-05-29 17:13:35 -0700319 }
Patrick Williams5b485792016-08-02 07:35:14 -0500320
Patrick Williams10d7aa12021-11-19 11:36:18 -0600321 return message_t(reply, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500322 }
Patrick Williams10d7aa12021-11-19 11:36:18 -0600323 auto call(message_t& m, std::optional<SdBusDuration> timeout = std::nullopt)
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800324 {
325 return call(m, timeout ? timeout->count() : 0);
326 }
Patrick Williams5b485792016-08-02 07:35:14 -0500327
328 /** @brief Perform a message call, ignoring the reply.
329 *
330 * @param[in] m - The method_call message.
331 * @param[in] timeout_us - The timeout for the method call.
332 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600333 void call_noreply(message_t& m, uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500334 {
William A. Kennington III55d66862018-05-29 17:13:35 -0700335 sd_bus_error error = SD_BUS_ERROR_NULL;
336 int r = _intf->sd_bus_call(_bus.get(), m.get(), timeout_us, &error,
337 nullptr);
338 if (r < 0)
339 {
William A. Kennington III68cb1702018-06-22 19:35:48 -0700340 throw exception::SdBusError(&error, "sd_bus_call noreply");
William A. Kennington III55d66862018-05-29 17:13:35 -0700341 }
Patrick Williams5b485792016-08-02 07:35:14 -0500342 }
Patrick Williams10d7aa12021-11-19 11:36:18 -0600343 auto call_noreply(message_t& m,
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800344 std::optional<SdBusDuration> timeout = std::nullopt)
345 {
346 return call_noreply(m, timeout ? timeout->count() : 0);
347 }
Patrick Williams5b485792016-08-02 07:35:14 -0500348
William A. Kennington III5b701c62018-09-11 00:36:30 -0700349 /** @brief Perform a message call, ignoring the reply and any errors
350 * in the dbus stack.
351 *
352 * @param[in] m - The method_call message.
353 * @param[in] timeout_us - The timeout for the method call.
354 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600355 void call_noreply_noerror(message_t& m, uint64_t timeout_us)
William A. Kennington III5b701c62018-09-11 00:36:30 -0700356 {
357 try
358 {
359 call_noreply(m, timeout_us);
360 }
Patrick Williamsb4667652021-10-06 12:16:17 -0500361 catch (const exception::SdBusError&)
William A. Kennington III5b701c62018-09-11 00:36:30 -0700362 {
363 // Intentionally ignoring these sd_bus errors
364 }
365 }
Patrick Williams68052842020-05-15 11:29:10 -0500366 auto call_noreply_noerror(
Patrick Williams10d7aa12021-11-19 11:36:18 -0600367 message_t& m, std::optional<SdBusDuration> timeout = std::nullopt)
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800368 {
369 return call_noreply_noerror(m, timeout ? timeout->count() : 0);
370 }
William A. Kennington III5b701c62018-09-11 00:36:30 -0700371
Adriana Kobylakc5496772017-01-04 09:57:23 -0600372 /** @brief Get the bus unique name. Ex: ":1.11".
Patrick Ventureff095682018-04-13 20:54:32 -0700373 *
374 * @return The bus unique name.
375 */
Adriana Kobylakc5496772017-01-04 09:57:23 -0600376 auto get_unique_name()
377 {
378 const char* unique = nullptr;
Patrick Ventureff095682018-04-13 20:54:32 -0700379 _intf->sd_bus_get_unique_name(_bus.get(), &unique);
Adriana Kobylakc5496772017-01-04 09:57:23 -0600380 return std::string(unique);
381 }
382
Brad Bishopb4cc7d72018-12-06 15:27:48 -0500383 auto get_fd()
384 {
William A. Kennington IIIcb582e02018-06-28 18:01:01 -0700385 return _intf->sd_bus_get_fd(_bus.get());
James Feist284a0f92018-04-05 15:28:16 -0700386 }
387
Yi Li8ac39ee2017-01-16 16:21:51 +0800388 /** @brief Attach the bus with a sd-event event loop object.
389 *
390 * @param[in] event - sd_event object.
391 * @param[in] priority - priority of bus event source.
392 */
393 void attach_event(sd_event* event, int priority)
394 {
Patrick Ventureff095682018-04-13 20:54:32 -0700395 _intf->sd_bus_attach_event(_bus.get(), event, priority);
Yi Li8ac39ee2017-01-16 16:21:51 +0800396 }
397
398 /** @brief Detach the bus from its sd-event event loop object */
399 void detach_event()
400 {
Patrick Ventureff095682018-04-13 20:54:32 -0700401 _intf->sd_bus_detach_event(_bus.get());
Yi Li8ac39ee2017-01-16 16:21:51 +0800402 }
403
404 /** @brief Get the sd-event event loop object of the bus */
405 auto get_event()
406 {
Patrick Ventureff095682018-04-13 20:54:32 -0700407 return _intf->sd_bus_get_event(_bus.get());
Yi Li8ac39ee2017-01-16 16:21:51 +0800408 }
409
Brad Bishopd2945572017-02-15 23:40:15 -0500410 /** @brief Wrapper for sd_bus_emit_interfaces_added_strv
411 *
412 * In general the similarly named server::object::object API should
413 * be used to manage emission of ObjectManager signals in favor
414 * of this one. Provided here for complex usage scenarios.
415 *
416 * @param[in] path - The path to forward.
417 * @param[in] ifaces - The interfaces to forward.
418 */
419 void emit_interfaces_added(const char* path,
Patrick Williams32ffb032020-10-12 12:17:48 -0500420 const std::vector<std::string>& ifaces);
Brad Bishopd2945572017-02-15 23:40:15 -0500421
422 /** @brief Wrapper for sd_bus_emit_interfaces_removed_strv
423 *
424 * In general the similarly named server::object::object API should
425 * be used to manage emission of ObjectManager signals in favor
426 * of this one. Provided here for complex usage scenarios.
427 *
428 * @param[in] path - The path to forward.
429 * @param[in] ifaces - The interfaces to forward.
430 */
431 void emit_interfaces_removed(const char* path,
Patrick Williams32ffb032020-10-12 12:17:48 -0500432 const std::vector<std::string>& ifaces);
Brad Bishopd2945572017-02-15 23:40:15 -0500433
Brad Bishop9a0baf52017-02-03 20:05:22 -0500434 /** @brief Wrapper for sd_bus_emit_object_added
435 *
436 * In general the similarly named server::object::object API should
437 * be used to manage emission of ObjectManager signals in favor
438 * of this one. Provided here for complex usage scenarios.
439 *
440 * @param[in] path - The path to forward to sd_bus_emit_object_added
441 */
442 void emit_object_added(const char* path)
443 {
Patrick Ventureff095682018-04-13 20:54:32 -0700444 _intf->sd_bus_emit_object_added(_bus.get(), path);
Brad Bishop9a0baf52017-02-03 20:05:22 -0500445 }
446
447 /** @brief Wrapper for sd_bus_emit_object_removed
448 *
449 * In general the similarly named server::object::object API should
450 * be used to manage emission of ObjectManager signals in favor
451 * of this one. Provided here for complex usage scenarios.
452 *
453 * @param[in] path - The path to forward to sd_bus_emit_object_removed
454 */
455 void emit_object_removed(const char* path)
456 {
Patrick Ventureff095682018-04-13 20:54:32 -0700457 _intf->sd_bus_emit_object_removed(_bus.get(), path);
Brad Bishop9a0baf52017-02-03 20:05:22 -0500458 }
459
Patrick Williamsb4041d42017-04-27 21:49:00 -0500460 /** @brief Wrapper for sd_bus_list_names.
461 *
462 * @return A vector of strings containing the 'acquired' names from
463 * sd_bus_list_names.
464 */
465 auto list_names_acquired()
466 {
467 char** names = nullptr;
468
Patrick Ventureff095682018-04-13 20:54:32 -0700469 _intf->sd_bus_list_names(_bus.get(), &names, nullptr);
Patrick Williamsb4041d42017-04-27 21:49:00 -0500470
471 std::vector<std::string> result;
Patrick Ventureff095682018-04-13 20:54:32 -0700472 for (auto ptr = names; ptr && *ptr; ++ptr)
Patrick Williamsb4041d42017-04-27 21:49:00 -0500473 {
474 result.push_back(*ptr);
475 free(*ptr);
476 }
477 free(names);
478
479 return result;
480 }
481
Patrick Ventureb9a1e192018-04-16 09:40:21 -0700482 /** @brief Get the SdBusInterface used by this bus.
483 *
484 * @return A pointer to the SdBusInterface used by this bus.
485 */
486 sdbusplus::SdBusInterface* getInterface()
487 {
488 return _intf;
489 }
490
Hannu Lounento90f8d9b2023-03-13 11:05:08 +0200491 void set_current_exception(std::exception_ptr exception)
492 {
493 current_exception = exception;
494 }
495
Patrick Williams66492212021-11-19 16:49:28 -0600496 friend struct details::bus_friend;
Patrick Williams13f1ef72016-10-17 14:09:33 -0500497
James Feist284a0f92018-04-05 15:28:16 -0700498 protected:
Patrick Williams66492212021-11-19 16:49:28 -0600499 busp_t get() noexcept
Patrick Ventureff095682018-04-13 20:54:32 -0700500 {
501 return _bus.get();
502 }
503 sdbusplus::SdBusInterface* _intf;
504 details::bus _bus;
Hannu Lounento90f8d9b2023-03-13 11:05:08 +0200505
506 private:
507 std::exception_ptr current_exception;
Patrick Williams5b485792016-08-02 07:35:14 -0500508};
509
Patrick Ventureff095682018-04-13 20:54:32 -0700510inline bus::bus(busp_t b, sdbusplus::SdBusInterface* intf) :
Brad Bishop75834602018-12-11 08:42:53 -0500511 _intf(intf), _bus(_intf->sd_bus_ref(b), details::BusDeleter(intf))
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500512{
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500513 // Emitting object added causes a message to get the properties
514 // which can trigger a 'transaction' in the server bindings. If
515 // the bus isn't up far enough, this causes an assert deep in
516 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
517 // enough to avoid the assert.
518 if (b != nullptr)
519 {
520 get_unique_name();
521 }
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500522}
523
Brad Bishop75834602018-12-11 08:42:53 -0500524inline bus::bus(busp_t b) :
525 _intf(&sdbus_impl),
526 _bus(_intf->sd_bus_ref(b), details::BusDeleter(&sdbus_impl))
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600527{
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600528 // Emitting object added causes a message to get the properties
529 // which can trigger a 'transaction' in the server bindings. If
530 // the bus isn't up far enough, this causes an assert deep in
531 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
532 // enough to avoid the assert.
533 if (b != nullptr)
534 {
535 get_unique_name();
536 }
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600537}
538
Brad Bishop75834602018-12-11 08:42:53 -0500539inline bus::bus(busp_t b, std::false_type) :
540 _intf(&sdbus_impl), _bus(b, details::BusDeleter(&sdbus_impl))
Patrick Ventureff095682018-04-13 20:54:32 -0700541{
Patrick Ventureff095682018-04-13 20:54:32 -0700542 // Emitting object added causes a message to get the properties
543 // which can trigger a 'transaction' in the server bindings. If
544 // the bus isn't up far enough, this causes an assert deep in
545 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
546 // enough to avoid the assert.
547 if (b != nullptr)
548 {
549 get_unique_name();
550 }
Patrick Ventureff095682018-04-13 20:54:32 -0700551}
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600552
Vernon Mauery8ca60252018-11-08 14:55:34 -0800553/* Create a new default connection: system bus if root, session bus if user */
Brad Bishopaed81792016-10-12 08:40:34 -0400554inline bus new_default()
Patrick Williams5b485792016-08-02 07:35:14 -0500555{
556 sd_bus* b = nullptr;
Vernon Mauery8ca60252018-11-08 14:55:34 -0800557 sd_bus_default(&b);
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500558 return bus(b, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500559}
560
Vernon Mauery8ca60252018-11-08 14:55:34 -0800561/* Create a new default connection to the session bus */
562inline bus new_default_user()
563{
564 sd_bus* b = nullptr;
565 sd_bus_default_user(&b);
566 return bus(b, std::false_type());
567}
568
569/* Create a new default connection to the system bus */
570inline bus new_default_system()
571{
572 sd_bus* b = nullptr;
573 sd_bus_default_system(&b);
574 return bus(b, std::false_type());
575}
576
577/* WARNING: THESE ARE NOT THE FUNCTIONS YOU ARE LOOKING FOR! */
William A. Kennington III34fdbf32018-12-19 17:33:42 -0800578inline bus new_bus()
579{
580 sd_bus* b = nullptr;
581 sd_bus_open(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800582 bus bus(b, std::false_type());
583 bus.set_should_close(true);
584 return bus;
William A. Kennington III34fdbf32018-12-19 17:33:42 -0800585}
586
Brad Bishopaed81792016-10-12 08:40:34 -0400587inline bus new_user()
Patrick Williams5b485792016-08-02 07:35:14 -0500588{
589 sd_bus* b = nullptr;
590 sd_bus_open_user(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800591 bus bus(b, std::false_type());
592 bus.set_should_close(true);
593 return bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500594}
595
Brad Bishopaed81792016-10-12 08:40:34 -0400596inline bus new_system()
Patrick Williams5b485792016-08-02 07:35:14 -0500597{
598 sd_bus* b = nullptr;
599 sd_bus_open_system(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800600 bus bus(b, std::false_type());
601 bus.set_should_close(true);
602 return bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500603}
604
Patrick Williams66492212021-11-19 16:49:28 -0600605namespace details
606{
607
608// Some sdbusplus classes need to be able to pass the underlying bus pointer
609// along to sd_bus calls, but we don't want to make it available for everyone.
610// Define a class which can be inherited explicitly (intended for internal users
611// only) to get the underlying bus pointer.
612struct bus_friend
613{
614 static busp_t get_busp(sdbusplus::bus::bus& b) noexcept
615 {
616 return b.get();
617 }
618};
619
620} // namespace details
621
Patrick Williams5b485792016-08-02 07:35:14 -0500622} // namespace bus
623
Patrick Williams0f282c42021-11-19 11:36:18 -0600624using bus_t = bus::bus;
625
Adriana Kobylak63122252017-01-26 15:09:00 -0600626/** @brief Get the dbus bus from the message.
627 *
628 * @return The dbus bus.
629 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600630inline auto message_t::get_bus() const
Adriana Kobylak63122252017-01-26 15:09:00 -0600631{
632 sd_bus* b = nullptr;
Patrick Venture4c3427c2018-04-13 17:09:55 -0700633 b = _intf->sd_bus_message_get_bus(_msg.get());
Patrick Williams0f282c42021-11-19 11:36:18 -0600634 return bus_t(b, _intf);
Adriana Kobylak63122252017-01-26 15:09:00 -0600635}
636
Patrick Williams5b485792016-08-02 07:35:14 -0500637} // namespace sdbusplus
Patrick Williams0c8136a2021-08-28 14:42:31 -0500638
639#ifdef __clang__
640#pragma clang diagnostic pop
641#endif