blob: 294db225d03ee497fd4d6a6c9991b8f64aa14190 [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>
Patrick Venture2ea15b72018-06-22 08:41:18 -070012#include <memory>
William A. Kennington IIIb5a84462019-03-06 16:46:57 -080013#include <optional>
Patrick Venture2ea15b72018-06-22 08:41:18 -070014#include <string>
Patrick Venture2ea15b72018-06-22 08:41:18 -070015#include <vector>
Patrick Ventureff095682018-04-13 20:54:32 -070016
Patrick Williams0c8136a2021-08-28 14:42:31 -050017#ifdef __clang__
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wc99-extensions"
20#endif
21
Patrick Williams5b485792016-08-02 07:35:14 -050022namespace sdbusplus
23{
Patrick Williams13f1ef72016-10-17 14:09:33 -050024
Patrick Williams5b485792016-08-02 07:35:14 -050025namespace bus
26{
27
28using busp_t = sd_bus*;
Ed Tanous8cd7a4a2019-03-13 16:41:49 -070029struct bus;
Patrick Williams5b485792016-08-02 07:35:14 -050030
31/** @brief Get an instance of the 'default' bus. */
32bus new_default();
33/** @brief Get an instance of the 'user' session bus. */
34bus new_user();
35/** @brief Get an instance of the 'system' bus. */
36bus new_system();
37
38namespace details
39{
40
41/** @brief unique_ptr functor to release a bus reference. */
42struct BusDeleter
43{
Brad Bishop75834602018-12-11 08:42:53 -050044 BusDeleter() = delete;
Patrick Williamsf289c652022-08-26 10:43:10 -050045 explicit BusDeleter(SdBusInterface* interface) : m_interface(interface) {}
Patrick Williamsba6f50c2017-04-18 11:38:30 -050046
Brad Bishop75834602018-12-11 08:42:53 -050047 void operator()(sd_bus* ptr) const
48 {
49 (m_interface->*deleter)(ptr);
50 }
51
52 SdBusInterface* m_interface;
William A. Kennington III062205d2018-12-19 17:34:13 -080053 decltype(&SdBusInterface::sd_bus_unref) deleter =
54 &SdBusInterface::sd_bus_unref;
Patrick Williams5b485792016-08-02 07:35:14 -050055};
56
Brad Bishopd2945572017-02-15 23:40:15 -050057/** @brief Convert a vector of strings to c-style char** array. */
58class Strv
59{
Brad Bishopb4cc7d72018-12-06 15:27:48 -050060 public:
61 ~Strv() = default;
62 Strv() = delete;
63 Strv(const Strv&) = delete;
64 Strv& operator=(const Strv&) = delete;
65 Strv(Strv&&) = default;
66 Strv& operator=(Strv&&) = default;
Brad Bishopd2945572017-02-15 23:40:15 -050067
Brad Bishopb4cc7d72018-12-06 15:27:48 -050068 explicit Strv(const std::vector<std::string>& v)
69 {
70 std::transform(v.begin(), v.end(), std::back_inserter(ptrs),
71 [](const auto& i) { return i.c_str(); });
72 ptrs.push_back(nullptr);
73 }
Brad Bishopd2945572017-02-15 23:40:15 -050074
Patrick Williams4b646232021-02-22 13:50:48 -060075 explicit operator char**()
Brad Bishopb4cc7d72018-12-06 15:27:48 -050076 {
77 return const_cast<char**>(&ptrs.front());
78 }
Brad Bishopd2945572017-02-15 23:40:15 -050079
Brad Bishopb4cc7d72018-12-06 15:27:48 -050080 private:
81 std::vector<const char*> ptrs;
Brad Bishopd2945572017-02-15 23:40:15 -050082};
83
Patrick Williams5b485792016-08-02 07:35:14 -050084/* @brief Alias 'bus' to a unique_ptr type for auto-release. */
85using bus = std::unique_ptr<sd_bus, BusDeleter>;
86
Patrick Williams66492212021-11-19 16:49:28 -060087struct bus_friend;
88
Patrick Williams5b485792016-08-02 07:35:14 -050089} // namespace details
90
91/** @class bus
92 * @brief Provides C++ bindings to the sd_bus_* class functions.
93 */
94struct bus
95{
Patrick Ventureff095682018-04-13 20:54:32 -070096 /* Define all of the basic class operations:
97 * Not allowed:
98 * - Default constructor to avoid nullptrs.
99 * - Copy operations due to internal unique_ptr.
100 * Allowed:
101 * - Move operations.
102 * - Destructor.
103 */
Patrick Williams5b485792016-08-02 07:35:14 -0500104 bus() = delete;
105 bus(const bus&) = delete;
106 bus& operator=(const bus&) = delete;
Patrick Ventureff095682018-04-13 20:54:32 -0700107
Patrick Williams5b485792016-08-02 07:35:14 -0500108 bus(bus&&) = default;
109 bus& operator=(bus&&) = default;
110 ~bus() = default;
111
Patrick Ventureff095682018-04-13 20:54:32 -0700112 bus(busp_t b, sdbusplus::SdBusInterface* intf);
113
Patrick Williams5b485792016-08-02 07:35:14 -0500114 /** @brief Conversion constructor from 'busp_t'.
115 *
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500116 * Increments ref-count of the bus-pointer and releases it when done.
Patrick Williams5b485792016-08-02 07:35:14 -0500117 */
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600118 explicit bus(busp_t b);
Patrick Williams5b485792016-08-02 07:35:14 -0500119
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500120 /** @brief Constructor for 'bus'.
121 *
122 * Takes ownership of the bus-pointer and releases it when done.
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500123 */
124 bus(busp_t b, std::false_type);
125
William A. Kennington III062205d2018-12-19 17:34:13 -0800126 /** @brief Sets the bus to be closed when this handle is destroyed. */
127 void set_should_close(bool shouldClose)
128 {
129 if (shouldClose)
130 {
131 _bus.get_deleter().deleter =
132 &SdBusInterface::sd_bus_flush_close_unref;
133 }
134 else
135 {
136 _bus.get_deleter().deleter = &SdBusInterface::sd_bus_unref;
137 }
138 }
139
Patrick Williams5b485792016-08-02 07:35:14 -0500140 /** @brief Release ownership of the stored bus-pointer. */
Patrick Ventureff095682018-04-13 20:54:32 -0700141 busp_t release()
142 {
143 return _bus.release();
144 }
Patrick Williams5b485792016-08-02 07:35:14 -0500145
William A. Kennington III42f6ad52018-12-19 17:32:30 -0800146 /** @brief Flush all of the outstanding work on the bus. */
147 void flush()
148 {
149 int r = _intf->sd_bus_flush(_bus.get());
150 if (r < 0)
151 {
152 throw exception::SdBusError(-r, "sd_bus_flush");
153 }
154 }
155
156 /** @brief Close the connection to the dbus daemon. */
157 void close()
158 {
159 _intf->sd_bus_close(_bus.get());
160 }
161
William A. Kennington III5d81ca22022-11-22 02:28:17 -0800162 /** @brief Determine if the bus is open to the broker */
163 bool is_open()
164 {
165 int r = _intf->sd_bus_is_open(_bus.get());
166 if (r < 0)
167 {
168 throw exception::SdBusError(-r, "sd_bus_is_open");
169 }
170 return r;
171 }
172
Patrick Williams5b485792016-08-02 07:35:14 -0500173 /** @brief Wait for new dbus messages or signals.
174 *
175 * @param[in] timeout_us - Timeout in usec.
176 */
William A. Kennington III94865b32022-11-21 18:02:09 -0800177 int wait(uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500178 {
William A. Kennington III94865b32022-11-21 18:02:09 -0800179 int r = _intf->sd_bus_wait(_bus.get(), timeout_us);
180 if (r < 0)
181 {
182 throw exception::SdBusError(-r, "sd_bus_wait");
183 }
184 return r;
Patrick Williams5b485792016-08-02 07:35:14 -0500185 }
William A. Kennington III94865b32022-11-21 18:02:09 -0800186
187 int wait(std::optional<SdBusDuration> timeout = std::nullopt)
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800188 {
William A. Kennington III94865b32022-11-21 18:02:09 -0800189 return wait(timeout ? timeout->count() : UINT64_MAX);
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800190 }
Patrick Williams5b485792016-08-02 07:35:14 -0500191
192 /** @brief Process waiting dbus messages or signals. */
193 auto process()
194 {
195 sd_bus_message* m = nullptr;
William A. Kennington III49e4bdc2018-06-05 23:28:02 -0700196 int r = _intf->sd_bus_process(_bus.get(), &m);
197 if (r < 0)
198 {
199 throw exception::SdBusError(-r, "sd_bus_process");
200 }
Patrick Williams5b485792016-08-02 07:35:14 -0500201
Patrick Williams10d7aa12021-11-19 11:36:18 -0600202 return message_t(m, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500203 }
204
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500205 /** @brief Process waiting dbus messages or signals, discarding unhandled.
206 */
James Feistb5755182018-07-16 10:30:08 -0700207 auto process_discard()
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500208 {
William A. Kennington III49e4bdc2018-06-05 23:28:02 -0700209 int r = _intf->sd_bus_process(_bus.get(), nullptr);
210 if (r < 0)
211 {
212 throw exception::SdBusError(-r, "sd_bus_process discard");
213 }
James Feistb5755182018-07-16 10:30:08 -0700214 return r > 0;
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500215 }
216
Nan Zhou25e2a092022-09-01 03:47:19 +0000217 /** @brief Process waiting dbus messages or signals forever, discarding
218 * unhandled.
219 */
Brad Bishope8c76142022-09-29 11:07:00 -0400220 [[noreturn]] void process_loop()
Nan Zhou25e2a092022-09-01 03:47:19 +0000221 {
222 while (true)
223 {
224 process_discard();
225 wait();
226 }
227 }
228
Patrick Williams5b485792016-08-02 07:35:14 -0500229 /** @brief Claim a service name on the dbus.
230 *
231 * @param[in] service - The service name to claim.
232 */
233 void request_name(const char* service)
234 {
Waqar Hameed841d8d32018-10-04 13:35:43 +0200235 int r = _intf->sd_bus_request_name(_bus.get(), service, 0);
236 if (r < 0)
237 {
238 throw exception::SdBusError(-r, "sd_bus_request_name");
239 }
Patrick Williams5b485792016-08-02 07:35:14 -0500240 }
241
242 /** @brief Create a method_call message.
243 *
244 * @param[in] service - The service to call.
245 * @param[in] objpath - The object's path for the call.
246 * @param[in] interf - The object's interface to call.
247 * @param[in] method - The object's method to call.
248 *
249 * @return A newly constructed message.
250 */
251 auto new_method_call(const char* service, const char* objpath,
252 const char* interf, const char* method)
253 {
254 sd_bus_message* m = nullptr;
William A. Kennington IIIec9236d2018-06-05 23:30:15 -0700255 int r = _intf->sd_bus_message_new_method_call(_bus.get(), &m, service,
256 objpath, interf, method);
257 if (r < 0)
258 {
259 throw exception::SdBusError(-r, "sd_bus_message_new_method_call");
260 }
Patrick Williams5b485792016-08-02 07:35:14 -0500261
Patrick Williams10d7aa12021-11-19 11:36:18 -0600262 return message_t(m, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500263 }
264
Patrick Williams20d82462016-10-18 08:01:33 -0500265 /** @brief Create a signal message.
266 *
267 * @param[in] objpath - The object's path for the signal.
268 * @param[in] interf - The object's interface for the signal.
269 * @param[in] member - The signal name.
270 *
271 * @return A newly constructed message.
272 */
273 auto new_signal(const char* objpath, const char* interf, const char* member)
274 {
275 sd_bus_message* m = nullptr;
William A. Kennington IIIec9236d2018-06-05 23:30:15 -0700276 int r = _intf->sd_bus_message_new_signal(_bus.get(), &m, objpath,
277 interf, member);
278 if (r < 0)
279 {
280 throw exception::SdBusError(-r, "sd_bus_message_new_signal");
281 }
Patrick Williams20d82462016-10-18 08:01:33 -0500282
Patrick Williams10d7aa12021-11-19 11:36:18 -0600283 return message_t(m, _intf, std::false_type());
Patrick Williams20d82462016-10-18 08:01:33 -0500284 }
285
Patrick Williams5b485792016-08-02 07:35:14 -0500286 /** @brief Perform a message call.
William A. Kennington III079fb852018-10-12 13:36:31 -0700287 * Errors generated by this call come from underlying dbus
288 * related errors *AND* from any method call that results
289 * in a METHOD_ERROR. This means you do not need to check
290 * is_method_error() on the returned message.
Patrick Williams5b485792016-08-02 07:35:14 -0500291 *
292 * @param[in] m - The method_call message.
293 * @param[in] timeout_us - The timeout for the method call.
294 *
295 * @return The response message.
296 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600297 auto call(message_t& m, uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500298 {
William A. Kennington III55d66862018-05-29 17:13:35 -0700299 sd_bus_error error = SD_BUS_ERROR_NULL;
Patrick Williams5b485792016-08-02 07:35:14 -0500300 sd_bus_message* reply = nullptr;
Patrick Williams1a25a102022-09-29 17:18:26 -0500301 int r = _intf->sd_bus_call(_bus.get(), m.get(), timeout_us, &error,
302 &reply);
William A. Kennington III55d66862018-05-29 17:13:35 -0700303 if (r < 0)
304 {
William A. Kennington III68cb1702018-06-22 19:35:48 -0700305 throw exception::SdBusError(&error, "sd_bus_call");
William A. Kennington III55d66862018-05-29 17:13:35 -0700306 }
Patrick Williams5b485792016-08-02 07:35:14 -0500307
Patrick Williams10d7aa12021-11-19 11:36:18 -0600308 return message_t(reply, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500309 }
Patrick Williams10d7aa12021-11-19 11:36:18 -0600310 auto call(message_t& m, std::optional<SdBusDuration> timeout = std::nullopt)
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800311 {
312 return call(m, timeout ? timeout->count() : 0);
313 }
Patrick Williams5b485792016-08-02 07:35:14 -0500314
315 /** @brief Perform a message call, ignoring the reply.
316 *
317 * @param[in] m - The method_call message.
318 * @param[in] timeout_us - The timeout for the method call.
319 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600320 void call_noreply(message_t& m, uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500321 {
William A. Kennington III55d66862018-05-29 17:13:35 -0700322 sd_bus_error error = SD_BUS_ERROR_NULL;
323 int r = _intf->sd_bus_call(_bus.get(), m.get(), timeout_us, &error,
324 nullptr);
325 if (r < 0)
326 {
William A. Kennington III68cb1702018-06-22 19:35:48 -0700327 throw exception::SdBusError(&error, "sd_bus_call noreply");
William A. Kennington III55d66862018-05-29 17:13:35 -0700328 }
Patrick Williams5b485792016-08-02 07:35:14 -0500329 }
Patrick Williams10d7aa12021-11-19 11:36:18 -0600330 auto call_noreply(message_t& m,
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800331 std::optional<SdBusDuration> timeout = std::nullopt)
332 {
333 return call_noreply(m, timeout ? timeout->count() : 0);
334 }
Patrick Williams5b485792016-08-02 07:35:14 -0500335
William A. Kennington III5b701c62018-09-11 00:36:30 -0700336 /** @brief Perform a message call, ignoring the reply and any errors
337 * in the dbus stack.
338 *
339 * @param[in] m - The method_call message.
340 * @param[in] timeout_us - The timeout for the method call.
341 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600342 void call_noreply_noerror(message_t& m, uint64_t timeout_us)
William A. Kennington III5b701c62018-09-11 00:36:30 -0700343 {
344 try
345 {
346 call_noreply(m, timeout_us);
347 }
Patrick Williamsb4667652021-10-06 12:16:17 -0500348 catch (const exception::SdBusError&)
William A. Kennington III5b701c62018-09-11 00:36:30 -0700349 {
350 // Intentionally ignoring these sd_bus errors
351 }
352 }
Patrick Williams68052842020-05-15 11:29:10 -0500353 auto call_noreply_noerror(
Patrick Williams10d7aa12021-11-19 11:36:18 -0600354 message_t& m, std::optional<SdBusDuration> timeout = std::nullopt)
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800355 {
356 return call_noreply_noerror(m, timeout ? timeout->count() : 0);
357 }
William A. Kennington III5b701c62018-09-11 00:36:30 -0700358
Adriana Kobylakc5496772017-01-04 09:57:23 -0600359 /** @brief Get the bus unique name. Ex: ":1.11".
Patrick Ventureff095682018-04-13 20:54:32 -0700360 *
361 * @return The bus unique name.
362 */
Adriana Kobylakc5496772017-01-04 09:57:23 -0600363 auto get_unique_name()
364 {
365 const char* unique = nullptr;
Patrick Ventureff095682018-04-13 20:54:32 -0700366 _intf->sd_bus_get_unique_name(_bus.get(), &unique);
Adriana Kobylakc5496772017-01-04 09:57:23 -0600367 return std::string(unique);
368 }
369
Brad Bishopb4cc7d72018-12-06 15:27:48 -0500370 auto get_fd()
371 {
William A. Kennington IIIcb582e02018-06-28 18:01:01 -0700372 return _intf->sd_bus_get_fd(_bus.get());
James Feist284a0f92018-04-05 15:28:16 -0700373 }
374
Yi Li8ac39ee2017-01-16 16:21:51 +0800375 /** @brief Attach the bus with a sd-event event loop object.
376 *
377 * @param[in] event - sd_event object.
378 * @param[in] priority - priority of bus event source.
379 */
380 void attach_event(sd_event* event, int priority)
381 {
Patrick Ventureff095682018-04-13 20:54:32 -0700382 _intf->sd_bus_attach_event(_bus.get(), event, priority);
Yi Li8ac39ee2017-01-16 16:21:51 +0800383 }
384
385 /** @brief Detach the bus from its sd-event event loop object */
386 void detach_event()
387 {
Patrick Ventureff095682018-04-13 20:54:32 -0700388 _intf->sd_bus_detach_event(_bus.get());
Yi Li8ac39ee2017-01-16 16:21:51 +0800389 }
390
391 /** @brief Get the sd-event event loop object of the bus */
392 auto get_event()
393 {
Patrick Ventureff095682018-04-13 20:54:32 -0700394 return _intf->sd_bus_get_event(_bus.get());
Yi Li8ac39ee2017-01-16 16:21:51 +0800395 }
396
Brad Bishopd2945572017-02-15 23:40:15 -0500397 /** @brief Wrapper for sd_bus_emit_interfaces_added_strv
398 *
399 * In general the similarly named server::object::object API should
400 * be used to manage emission of ObjectManager signals in favor
401 * of this one. Provided here for complex usage scenarios.
402 *
403 * @param[in] path - The path to forward.
404 * @param[in] ifaces - The interfaces to forward.
405 */
406 void emit_interfaces_added(const char* path,
Patrick Williams32ffb032020-10-12 12:17:48 -0500407 const std::vector<std::string>& ifaces);
Brad Bishopd2945572017-02-15 23:40:15 -0500408
409 /** @brief Wrapper for sd_bus_emit_interfaces_removed_strv
410 *
411 * In general the similarly named server::object::object API should
412 * be used to manage emission of ObjectManager signals in favor
413 * of this one. Provided here for complex usage scenarios.
414 *
415 * @param[in] path - The path to forward.
416 * @param[in] ifaces - The interfaces to forward.
417 */
418 void emit_interfaces_removed(const char* path,
Patrick Williams32ffb032020-10-12 12:17:48 -0500419 const std::vector<std::string>& ifaces);
Brad Bishopd2945572017-02-15 23:40:15 -0500420
Brad Bishop9a0baf52017-02-03 20:05:22 -0500421 /** @brief Wrapper for sd_bus_emit_object_added
422 *
423 * In general the similarly named server::object::object API should
424 * be used to manage emission of ObjectManager signals in favor
425 * of this one. Provided here for complex usage scenarios.
426 *
427 * @param[in] path - The path to forward to sd_bus_emit_object_added
428 */
429 void emit_object_added(const char* path)
430 {
Patrick Ventureff095682018-04-13 20:54:32 -0700431 _intf->sd_bus_emit_object_added(_bus.get(), path);
Brad Bishop9a0baf52017-02-03 20:05:22 -0500432 }
433
434 /** @brief Wrapper for sd_bus_emit_object_removed
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_removed
441 */
442 void emit_object_removed(const char* path)
443 {
Patrick Ventureff095682018-04-13 20:54:32 -0700444 _intf->sd_bus_emit_object_removed(_bus.get(), path);
Brad Bishop9a0baf52017-02-03 20:05:22 -0500445 }
446
Patrick Williamsb4041d42017-04-27 21:49:00 -0500447 /** @brief Wrapper for sd_bus_list_names.
448 *
449 * @return A vector of strings containing the 'acquired' names from
450 * sd_bus_list_names.
451 */
452 auto list_names_acquired()
453 {
454 char** names = nullptr;
455
Patrick Ventureff095682018-04-13 20:54:32 -0700456 _intf->sd_bus_list_names(_bus.get(), &names, nullptr);
Patrick Williamsb4041d42017-04-27 21:49:00 -0500457
458 std::vector<std::string> result;
Patrick Ventureff095682018-04-13 20:54:32 -0700459 for (auto ptr = names; ptr && *ptr; ++ptr)
Patrick Williamsb4041d42017-04-27 21:49:00 -0500460 {
461 result.push_back(*ptr);
462 free(*ptr);
463 }
464 free(names);
465
466 return result;
467 }
468
Patrick Ventureb9a1e192018-04-16 09:40:21 -0700469 /** @brief Get the SdBusInterface used by this bus.
470 *
471 * @return A pointer to the SdBusInterface used by this bus.
472 */
473 sdbusplus::SdBusInterface* getInterface()
474 {
475 return _intf;
476 }
477
Patrick Williams66492212021-11-19 16:49:28 -0600478 friend struct details::bus_friend;
Patrick Williams13f1ef72016-10-17 14:09:33 -0500479
James Feist284a0f92018-04-05 15:28:16 -0700480 protected:
Patrick Williams66492212021-11-19 16:49:28 -0600481 busp_t get() noexcept
Patrick Ventureff095682018-04-13 20:54:32 -0700482 {
483 return _bus.get();
484 }
485 sdbusplus::SdBusInterface* _intf;
486 details::bus _bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500487};
488
Patrick Ventureff095682018-04-13 20:54:32 -0700489inline bus::bus(busp_t b, sdbusplus::SdBusInterface* intf) :
Brad Bishop75834602018-12-11 08:42:53 -0500490 _intf(intf), _bus(_intf->sd_bus_ref(b), details::BusDeleter(intf))
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500491{
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500492 // Emitting object added causes a message to get the properties
493 // which can trigger a 'transaction' in the server bindings. If
494 // the bus isn't up far enough, this causes an assert deep in
495 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
496 // enough to avoid the assert.
497 if (b != nullptr)
498 {
499 get_unique_name();
500 }
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500501}
502
Brad Bishop75834602018-12-11 08:42:53 -0500503inline bus::bus(busp_t b) :
504 _intf(&sdbus_impl),
505 _bus(_intf->sd_bus_ref(b), details::BusDeleter(&sdbus_impl))
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600506{
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600507 // Emitting object added causes a message to get the properties
508 // which can trigger a 'transaction' in the server bindings. If
509 // the bus isn't up far enough, this causes an assert deep in
510 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
511 // enough to avoid the assert.
512 if (b != nullptr)
513 {
514 get_unique_name();
515 }
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600516}
517
Brad Bishop75834602018-12-11 08:42:53 -0500518inline bus::bus(busp_t b, std::false_type) :
519 _intf(&sdbus_impl), _bus(b, details::BusDeleter(&sdbus_impl))
Patrick Ventureff095682018-04-13 20:54:32 -0700520{
Patrick Ventureff095682018-04-13 20:54:32 -0700521 // Emitting object added causes a message to get the properties
522 // which can trigger a 'transaction' in the server bindings. If
523 // the bus isn't up far enough, this causes an assert deep in
524 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
525 // enough to avoid the assert.
526 if (b != nullptr)
527 {
528 get_unique_name();
529 }
Patrick Ventureff095682018-04-13 20:54:32 -0700530}
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600531
Vernon Mauery8ca60252018-11-08 14:55:34 -0800532/* Create a new default connection: system bus if root, session bus if user */
Brad Bishopaed81792016-10-12 08:40:34 -0400533inline bus new_default()
Patrick Williams5b485792016-08-02 07:35:14 -0500534{
535 sd_bus* b = nullptr;
Vernon Mauery8ca60252018-11-08 14:55:34 -0800536 sd_bus_default(&b);
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500537 return bus(b, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500538}
539
Vernon Mauery8ca60252018-11-08 14:55:34 -0800540/* Create a new default connection to the session bus */
541inline bus new_default_user()
542{
543 sd_bus* b = nullptr;
544 sd_bus_default_user(&b);
545 return bus(b, std::false_type());
546}
547
548/* Create a new default connection to the system bus */
549inline bus new_default_system()
550{
551 sd_bus* b = nullptr;
552 sd_bus_default_system(&b);
553 return bus(b, std::false_type());
554}
555
556/* WARNING: THESE ARE NOT THE FUNCTIONS YOU ARE LOOKING FOR! */
William A. Kennington III34fdbf32018-12-19 17:33:42 -0800557inline bus new_bus()
558{
559 sd_bus* b = nullptr;
560 sd_bus_open(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800561 bus bus(b, std::false_type());
562 bus.set_should_close(true);
563 return bus;
William A. Kennington III34fdbf32018-12-19 17:33:42 -0800564}
565
Brad Bishopaed81792016-10-12 08:40:34 -0400566inline bus new_user()
Patrick Williams5b485792016-08-02 07:35:14 -0500567{
568 sd_bus* b = nullptr;
569 sd_bus_open_user(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800570 bus bus(b, std::false_type());
571 bus.set_should_close(true);
572 return bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500573}
574
Brad Bishopaed81792016-10-12 08:40:34 -0400575inline bus new_system()
Patrick Williams5b485792016-08-02 07:35:14 -0500576{
577 sd_bus* b = nullptr;
578 sd_bus_open_system(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800579 bus bus(b, std::false_type());
580 bus.set_should_close(true);
581 return bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500582}
583
Patrick Williams66492212021-11-19 16:49:28 -0600584namespace details
585{
586
587// Some sdbusplus classes need to be able to pass the underlying bus pointer
588// along to sd_bus calls, but we don't want to make it available for everyone.
589// Define a class which can be inherited explicitly (intended for internal users
590// only) to get the underlying bus pointer.
591struct bus_friend
592{
593 static busp_t get_busp(sdbusplus::bus::bus& b) noexcept
594 {
595 return b.get();
596 }
597};
598
599} // namespace details
600
Patrick Williams5b485792016-08-02 07:35:14 -0500601} // namespace bus
602
Patrick Williams0f282c42021-11-19 11:36:18 -0600603using bus_t = bus::bus;
604
Adriana Kobylak63122252017-01-26 15:09:00 -0600605/** @brief Get the dbus bus from the message.
606 *
607 * @return The dbus bus.
608 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600609inline auto message_t::get_bus() const
Adriana Kobylak63122252017-01-26 15:09:00 -0600610{
611 sd_bus* b = nullptr;
Patrick Venture4c3427c2018-04-13 17:09:55 -0700612 b = _intf->sd_bus_message_get_bus(_msg.get());
Patrick Williams0f282c42021-11-19 11:36:18 -0600613 return bus_t(b, _intf);
Adriana Kobylak63122252017-01-26 15:09:00 -0600614}
615
Patrick Williams5b485792016-08-02 07:35:14 -0500616} // namespace sdbusplus
Patrick Williams0c8136a2021-08-28 14:42:31 -0500617
618#ifdef __clang__
619#pragma clang diagnostic pop
620#endif