blob: 11e2d13ae517227403e7c208c03a3bf99f65ea6b [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
Patrick Williams5b485792016-08-02 07:35:14 -0500162 /** @brief Wait for new dbus messages or signals.
163 *
164 * @param[in] timeout_us - Timeout in usec.
165 */
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800166 void wait(uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500167 {
Patrick Ventureff095682018-04-13 20:54:32 -0700168 _intf->sd_bus_wait(_bus.get(), timeout_us);
Patrick Williams5b485792016-08-02 07:35:14 -0500169 }
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800170 void wait(std::optional<SdBusDuration> timeout = std::nullopt)
171 {
172 wait(timeout ? timeout->count() : UINT64_MAX);
173 }
Patrick Williams5b485792016-08-02 07:35:14 -0500174
175 /** @brief Process waiting dbus messages or signals. */
176 auto process()
177 {
178 sd_bus_message* m = nullptr;
William A. Kennington III49e4bdc2018-06-05 23:28:02 -0700179 int r = _intf->sd_bus_process(_bus.get(), &m);
180 if (r < 0)
181 {
182 throw exception::SdBusError(-r, "sd_bus_process");
183 }
Patrick Williams5b485792016-08-02 07:35:14 -0500184
Patrick Williams10d7aa12021-11-19 11:36:18 -0600185 return message_t(m, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500186 }
187
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500188 /** @brief Process waiting dbus messages or signals, discarding unhandled.
189 */
James Feistb5755182018-07-16 10:30:08 -0700190 auto process_discard()
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500191 {
William A. Kennington III49e4bdc2018-06-05 23:28:02 -0700192 int r = _intf->sd_bus_process(_bus.get(), nullptr);
193 if (r < 0)
194 {
195 throw exception::SdBusError(-r, "sd_bus_process discard");
196 }
James Feistb5755182018-07-16 10:30:08 -0700197 return r > 0;
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500198 }
199
Nan Zhou25e2a092022-09-01 03:47:19 +0000200 /** @brief Process waiting dbus messages or signals forever, discarding
201 * unhandled.
202 */
Brad Bishope8c76142022-09-29 11:07:00 -0400203 [[noreturn]] void process_loop()
Nan Zhou25e2a092022-09-01 03:47:19 +0000204 {
205 while (true)
206 {
207 process_discard();
208 wait();
209 }
210 }
211
Patrick Williams5b485792016-08-02 07:35:14 -0500212 /** @brief Claim a service name on the dbus.
213 *
214 * @param[in] service - The service name to claim.
215 */
216 void request_name(const char* service)
217 {
Waqar Hameed841d8d32018-10-04 13:35:43 +0200218 int r = _intf->sd_bus_request_name(_bus.get(), service, 0);
219 if (r < 0)
220 {
221 throw exception::SdBusError(-r, "sd_bus_request_name");
222 }
Patrick Williams5b485792016-08-02 07:35:14 -0500223 }
224
225 /** @brief Create a method_call message.
226 *
227 * @param[in] service - The service to call.
228 * @param[in] objpath - The object's path for the call.
229 * @param[in] interf - The object's interface to call.
230 * @param[in] method - The object's method to call.
231 *
232 * @return A newly constructed message.
233 */
234 auto new_method_call(const char* service, const char* objpath,
235 const char* interf, const char* method)
236 {
237 sd_bus_message* m = nullptr;
William A. Kennington IIIec9236d2018-06-05 23:30:15 -0700238 int r = _intf->sd_bus_message_new_method_call(_bus.get(), &m, service,
239 objpath, interf, method);
240 if (r < 0)
241 {
242 throw exception::SdBusError(-r, "sd_bus_message_new_method_call");
243 }
Patrick Williams5b485792016-08-02 07:35:14 -0500244
Patrick Williams10d7aa12021-11-19 11:36:18 -0600245 return message_t(m, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500246 }
247
Patrick Williams20d82462016-10-18 08:01:33 -0500248 /** @brief Create a signal message.
249 *
250 * @param[in] objpath - The object's path for the signal.
251 * @param[in] interf - The object's interface for the signal.
252 * @param[in] member - The signal name.
253 *
254 * @return A newly constructed message.
255 */
256 auto new_signal(const char* objpath, const char* interf, const char* member)
257 {
258 sd_bus_message* m = nullptr;
William A. Kennington IIIec9236d2018-06-05 23:30:15 -0700259 int r = _intf->sd_bus_message_new_signal(_bus.get(), &m, objpath,
260 interf, member);
261 if (r < 0)
262 {
263 throw exception::SdBusError(-r, "sd_bus_message_new_signal");
264 }
Patrick Williams20d82462016-10-18 08:01:33 -0500265
Patrick Williams10d7aa12021-11-19 11:36:18 -0600266 return message_t(m, _intf, std::false_type());
Patrick Williams20d82462016-10-18 08:01:33 -0500267 }
268
Patrick Williams5b485792016-08-02 07:35:14 -0500269 /** @brief Perform a message call.
William A. Kennington III079fb852018-10-12 13:36:31 -0700270 * Errors generated by this call come from underlying dbus
271 * related errors *AND* from any method call that results
272 * in a METHOD_ERROR. This means you do not need to check
273 * is_method_error() on the returned message.
Patrick Williams5b485792016-08-02 07:35:14 -0500274 *
275 * @param[in] m - The method_call message.
276 * @param[in] timeout_us - The timeout for the method call.
277 *
278 * @return The response message.
279 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600280 auto call(message_t& m, uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500281 {
William A. Kennington III55d66862018-05-29 17:13:35 -0700282 sd_bus_error error = SD_BUS_ERROR_NULL;
Patrick Williams5b485792016-08-02 07:35:14 -0500283 sd_bus_message* reply = nullptr;
Brad Bishopb4cc7d72018-12-06 15:27:48 -0500284 int r =
285 _intf->sd_bus_call(_bus.get(), m.get(), timeout_us, &error, &reply);
William A. Kennington III55d66862018-05-29 17:13:35 -0700286 if (r < 0)
287 {
William A. Kennington III68cb1702018-06-22 19:35:48 -0700288 throw exception::SdBusError(&error, "sd_bus_call");
William A. Kennington III55d66862018-05-29 17:13:35 -0700289 }
Patrick Williams5b485792016-08-02 07:35:14 -0500290
Patrick Williams10d7aa12021-11-19 11:36:18 -0600291 return message_t(reply, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500292 }
Patrick Williams10d7aa12021-11-19 11:36:18 -0600293 auto call(message_t& m, std::optional<SdBusDuration> timeout = std::nullopt)
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800294 {
295 return call(m, timeout ? timeout->count() : 0);
296 }
Patrick Williams5b485792016-08-02 07:35:14 -0500297
298 /** @brief Perform a message call, ignoring the reply.
299 *
300 * @param[in] m - The method_call message.
301 * @param[in] timeout_us - The timeout for the method call.
302 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600303 void call_noreply(message_t& m, uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500304 {
William A. Kennington III55d66862018-05-29 17:13:35 -0700305 sd_bus_error error = SD_BUS_ERROR_NULL;
306 int r = _intf->sd_bus_call(_bus.get(), m.get(), timeout_us, &error,
307 nullptr);
308 if (r < 0)
309 {
William A. Kennington III68cb1702018-06-22 19:35:48 -0700310 throw exception::SdBusError(&error, "sd_bus_call noreply");
William A. Kennington III55d66862018-05-29 17:13:35 -0700311 }
Patrick Williams5b485792016-08-02 07:35:14 -0500312 }
Patrick Williams10d7aa12021-11-19 11:36:18 -0600313 auto call_noreply(message_t& m,
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800314 std::optional<SdBusDuration> timeout = std::nullopt)
315 {
316 return call_noreply(m, timeout ? timeout->count() : 0);
317 }
Patrick Williams5b485792016-08-02 07:35:14 -0500318
William A. Kennington III5b701c62018-09-11 00:36:30 -0700319 /** @brief Perform a message call, ignoring the reply and any errors
320 * in the dbus stack.
321 *
322 * @param[in] m - The method_call message.
323 * @param[in] timeout_us - The timeout for the method call.
324 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600325 void call_noreply_noerror(message_t& m, uint64_t timeout_us)
William A. Kennington III5b701c62018-09-11 00:36:30 -0700326 {
327 try
328 {
329 call_noreply(m, timeout_us);
330 }
Patrick Williamsb4667652021-10-06 12:16:17 -0500331 catch (const exception::SdBusError&)
William A. Kennington III5b701c62018-09-11 00:36:30 -0700332 {
333 // Intentionally ignoring these sd_bus errors
334 }
335 }
Patrick Williams68052842020-05-15 11:29:10 -0500336 auto call_noreply_noerror(
Patrick Williams10d7aa12021-11-19 11:36:18 -0600337 message_t& m, std::optional<SdBusDuration> timeout = std::nullopt)
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800338 {
339 return call_noreply_noerror(m, timeout ? timeout->count() : 0);
340 }
William A. Kennington III5b701c62018-09-11 00:36:30 -0700341
Adriana Kobylakc5496772017-01-04 09:57:23 -0600342 /** @brief Get the bus unique name. Ex: ":1.11".
Patrick Ventureff095682018-04-13 20:54:32 -0700343 *
344 * @return The bus unique name.
345 */
Adriana Kobylakc5496772017-01-04 09:57:23 -0600346 auto get_unique_name()
347 {
348 const char* unique = nullptr;
Patrick Ventureff095682018-04-13 20:54:32 -0700349 _intf->sd_bus_get_unique_name(_bus.get(), &unique);
Adriana Kobylakc5496772017-01-04 09:57:23 -0600350 return std::string(unique);
351 }
352
Brad Bishopb4cc7d72018-12-06 15:27:48 -0500353 auto get_fd()
354 {
William A. Kennington IIIcb582e02018-06-28 18:01:01 -0700355 return _intf->sd_bus_get_fd(_bus.get());
James Feist284a0f92018-04-05 15:28:16 -0700356 }
357
Yi Li8ac39ee2017-01-16 16:21:51 +0800358 /** @brief Attach the bus with a sd-event event loop object.
359 *
360 * @param[in] event - sd_event object.
361 * @param[in] priority - priority of bus event source.
362 */
363 void attach_event(sd_event* event, int priority)
364 {
Patrick Ventureff095682018-04-13 20:54:32 -0700365 _intf->sd_bus_attach_event(_bus.get(), event, priority);
Yi Li8ac39ee2017-01-16 16:21:51 +0800366 }
367
368 /** @brief Detach the bus from its sd-event event loop object */
369 void detach_event()
370 {
Patrick Ventureff095682018-04-13 20:54:32 -0700371 _intf->sd_bus_detach_event(_bus.get());
Yi Li8ac39ee2017-01-16 16:21:51 +0800372 }
373
374 /** @brief Get the sd-event event loop object of the bus */
375 auto get_event()
376 {
Patrick Ventureff095682018-04-13 20:54:32 -0700377 return _intf->sd_bus_get_event(_bus.get());
Yi Li8ac39ee2017-01-16 16:21:51 +0800378 }
379
Brad Bishopd2945572017-02-15 23:40:15 -0500380 /** @brief Wrapper for sd_bus_emit_interfaces_added_strv
381 *
382 * In general the similarly named server::object::object API should
383 * be used to manage emission of ObjectManager signals in favor
384 * of this one. Provided here for complex usage scenarios.
385 *
386 * @param[in] path - The path to forward.
387 * @param[in] ifaces - The interfaces to forward.
388 */
389 void emit_interfaces_added(const char* path,
Patrick Williams32ffb032020-10-12 12:17:48 -0500390 const std::vector<std::string>& ifaces);
Brad Bishopd2945572017-02-15 23:40:15 -0500391
392 /** @brief Wrapper for sd_bus_emit_interfaces_removed_strv
393 *
394 * In general the similarly named server::object::object API should
395 * be used to manage emission of ObjectManager signals in favor
396 * of this one. Provided here for complex usage scenarios.
397 *
398 * @param[in] path - The path to forward.
399 * @param[in] ifaces - The interfaces to forward.
400 */
401 void emit_interfaces_removed(const char* path,
Patrick Williams32ffb032020-10-12 12:17:48 -0500402 const std::vector<std::string>& ifaces);
Brad Bishopd2945572017-02-15 23:40:15 -0500403
Brad Bishop9a0baf52017-02-03 20:05:22 -0500404 /** @brief Wrapper for sd_bus_emit_object_added
405 *
406 * In general the similarly named server::object::object API should
407 * be used to manage emission of ObjectManager signals in favor
408 * of this one. Provided here for complex usage scenarios.
409 *
410 * @param[in] path - The path to forward to sd_bus_emit_object_added
411 */
412 void emit_object_added(const char* path)
413 {
Patrick Ventureff095682018-04-13 20:54:32 -0700414 _intf->sd_bus_emit_object_added(_bus.get(), path);
Brad Bishop9a0baf52017-02-03 20:05:22 -0500415 }
416
417 /** @brief Wrapper for sd_bus_emit_object_removed
418 *
419 * In general the similarly named server::object::object API should
420 * be used to manage emission of ObjectManager signals in favor
421 * of this one. Provided here for complex usage scenarios.
422 *
423 * @param[in] path - The path to forward to sd_bus_emit_object_removed
424 */
425 void emit_object_removed(const char* path)
426 {
Patrick Ventureff095682018-04-13 20:54:32 -0700427 _intf->sd_bus_emit_object_removed(_bus.get(), path);
Brad Bishop9a0baf52017-02-03 20:05:22 -0500428 }
429
Patrick Williamsb4041d42017-04-27 21:49:00 -0500430 /** @brief Wrapper for sd_bus_list_names.
431 *
432 * @return A vector of strings containing the 'acquired' names from
433 * sd_bus_list_names.
434 */
435 auto list_names_acquired()
436 {
437 char** names = nullptr;
438
Patrick Ventureff095682018-04-13 20:54:32 -0700439 _intf->sd_bus_list_names(_bus.get(), &names, nullptr);
Patrick Williamsb4041d42017-04-27 21:49:00 -0500440
441 std::vector<std::string> result;
Patrick Ventureff095682018-04-13 20:54:32 -0700442 for (auto ptr = names; ptr && *ptr; ++ptr)
Patrick Williamsb4041d42017-04-27 21:49:00 -0500443 {
444 result.push_back(*ptr);
445 free(*ptr);
446 }
447 free(names);
448
449 return result;
450 }
451
Patrick Ventureb9a1e192018-04-16 09:40:21 -0700452 /** @brief Get the SdBusInterface used by this bus.
453 *
454 * @return A pointer to the SdBusInterface used by this bus.
455 */
456 sdbusplus::SdBusInterface* getInterface()
457 {
458 return _intf;
459 }
460
Patrick Williams66492212021-11-19 16:49:28 -0600461 friend struct details::bus_friend;
Patrick Williams13f1ef72016-10-17 14:09:33 -0500462
James Feist284a0f92018-04-05 15:28:16 -0700463 protected:
Patrick Williams66492212021-11-19 16:49:28 -0600464 busp_t get() noexcept
Patrick Ventureff095682018-04-13 20:54:32 -0700465 {
466 return _bus.get();
467 }
468 sdbusplus::SdBusInterface* _intf;
469 details::bus _bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500470};
471
Patrick Ventureff095682018-04-13 20:54:32 -0700472inline bus::bus(busp_t b, sdbusplus::SdBusInterface* intf) :
Brad Bishop75834602018-12-11 08:42:53 -0500473 _intf(intf), _bus(_intf->sd_bus_ref(b), details::BusDeleter(intf))
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500474{
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500475 // Emitting object added causes a message to get the properties
476 // which can trigger a 'transaction' in the server bindings. If
477 // the bus isn't up far enough, this causes an assert deep in
478 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
479 // enough to avoid the assert.
480 if (b != nullptr)
481 {
482 get_unique_name();
483 }
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500484}
485
Brad Bishop75834602018-12-11 08:42:53 -0500486inline bus::bus(busp_t b) :
487 _intf(&sdbus_impl),
488 _bus(_intf->sd_bus_ref(b), details::BusDeleter(&sdbus_impl))
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600489{
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600490 // Emitting object added causes a message to get the properties
491 // which can trigger a 'transaction' in the server bindings. If
492 // the bus isn't up far enough, this causes an assert deep in
493 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
494 // enough to avoid the assert.
495 if (b != nullptr)
496 {
497 get_unique_name();
498 }
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600499}
500
Brad Bishop75834602018-12-11 08:42:53 -0500501inline bus::bus(busp_t b, std::false_type) :
502 _intf(&sdbus_impl), _bus(b, details::BusDeleter(&sdbus_impl))
Patrick Ventureff095682018-04-13 20:54:32 -0700503{
Patrick Ventureff095682018-04-13 20:54:32 -0700504 // Emitting object added causes a message to get the properties
505 // which can trigger a 'transaction' in the server bindings. If
506 // the bus isn't up far enough, this causes an assert deep in
507 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
508 // enough to avoid the assert.
509 if (b != nullptr)
510 {
511 get_unique_name();
512 }
Patrick Ventureff095682018-04-13 20:54:32 -0700513}
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600514
Vernon Mauery8ca60252018-11-08 14:55:34 -0800515/* Create a new default connection: system bus if root, session bus if user */
Brad Bishopaed81792016-10-12 08:40:34 -0400516inline bus new_default()
Patrick Williams5b485792016-08-02 07:35:14 -0500517{
518 sd_bus* b = nullptr;
Vernon Mauery8ca60252018-11-08 14:55:34 -0800519 sd_bus_default(&b);
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500520 return bus(b, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500521}
522
Vernon Mauery8ca60252018-11-08 14:55:34 -0800523/* Create a new default connection to the session bus */
524inline bus new_default_user()
525{
526 sd_bus* b = nullptr;
527 sd_bus_default_user(&b);
528 return bus(b, std::false_type());
529}
530
531/* Create a new default connection to the system bus */
532inline bus new_default_system()
533{
534 sd_bus* b = nullptr;
535 sd_bus_default_system(&b);
536 return bus(b, std::false_type());
537}
538
539/* WARNING: THESE ARE NOT THE FUNCTIONS YOU ARE LOOKING FOR! */
William A. Kennington III34fdbf32018-12-19 17:33:42 -0800540inline bus new_bus()
541{
542 sd_bus* b = nullptr;
543 sd_bus_open(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800544 bus bus(b, std::false_type());
545 bus.set_should_close(true);
546 return bus;
William A. Kennington III34fdbf32018-12-19 17:33:42 -0800547}
548
Brad Bishopaed81792016-10-12 08:40:34 -0400549inline bus new_user()
Patrick Williams5b485792016-08-02 07:35:14 -0500550{
551 sd_bus* b = nullptr;
552 sd_bus_open_user(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800553 bus bus(b, std::false_type());
554 bus.set_should_close(true);
555 return bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500556}
557
Brad Bishopaed81792016-10-12 08:40:34 -0400558inline bus new_system()
Patrick Williams5b485792016-08-02 07:35:14 -0500559{
560 sd_bus* b = nullptr;
561 sd_bus_open_system(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800562 bus bus(b, std::false_type());
563 bus.set_should_close(true);
564 return bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500565}
566
Patrick Williams66492212021-11-19 16:49:28 -0600567namespace details
568{
569
570// Some sdbusplus classes need to be able to pass the underlying bus pointer
571// along to sd_bus calls, but we don't want to make it available for everyone.
572// Define a class which can be inherited explicitly (intended for internal users
573// only) to get the underlying bus pointer.
574struct bus_friend
575{
576 static busp_t get_busp(sdbusplus::bus::bus& b) noexcept
577 {
578 return b.get();
579 }
580};
581
582} // namespace details
583
Patrick Williams5b485792016-08-02 07:35:14 -0500584} // namespace bus
585
Patrick Williams0f282c42021-11-19 11:36:18 -0600586using bus_t = bus::bus;
587
Adriana Kobylak63122252017-01-26 15:09:00 -0600588/** @brief Get the dbus bus from the message.
589 *
590 * @return The dbus bus.
591 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600592inline auto message_t::get_bus() const
Adriana Kobylak63122252017-01-26 15:09:00 -0600593{
594 sd_bus* b = nullptr;
Patrick Venture4c3427c2018-04-13 17:09:55 -0700595 b = _intf->sd_bus_message_get_bus(_msg.get());
Patrick Williams0f282c42021-11-19 11:36:18 -0600596 return bus_t(b, _intf);
Adriana Kobylak63122252017-01-26 15:09:00 -0600597}
598
Patrick Williams5b485792016-08-02 07:35:14 -0500599} // namespace sdbusplus
Patrick Williams0c8136a2021-08-28 14:42:31 -0500600
601#ifdef __clang__
602#pragma clang diagnostic pop
603#endif