blob: 874c364bcdb8c35ec07613a22162d75de6ca5bdc [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;
45 explicit BusDeleter(SdBusInterface* interface) : m_interface(interface)
Patrick Williams127b8ab2020-05-21 15:24:19 -050046 {}
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
Patrick Williams5b485792016-08-02 07:35:14 -0500163 /** @brief Wait for new dbus messages or signals.
164 *
165 * @param[in] timeout_us - Timeout in usec.
166 */
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800167 void wait(uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500168 {
Patrick Ventureff095682018-04-13 20:54:32 -0700169 _intf->sd_bus_wait(_bus.get(), timeout_us);
Patrick Williams5b485792016-08-02 07:35:14 -0500170 }
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800171 void wait(std::optional<SdBusDuration> timeout = std::nullopt)
172 {
173 wait(timeout ? timeout->count() : UINT64_MAX);
174 }
Patrick Williams5b485792016-08-02 07:35:14 -0500175
176 /** @brief Process waiting dbus messages or signals. */
177 auto process()
178 {
179 sd_bus_message* m = nullptr;
William A. Kennington III49e4bdc2018-06-05 23:28:02 -0700180 int r = _intf->sd_bus_process(_bus.get(), &m);
181 if (r < 0)
182 {
183 throw exception::SdBusError(-r, "sd_bus_process");
184 }
Patrick Williams5b485792016-08-02 07:35:14 -0500185
Patrick Williams10d7aa12021-11-19 11:36:18 -0600186 return message_t(m, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500187 }
188
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500189 /** @brief Process waiting dbus messages or signals, discarding unhandled.
190 */
James Feistb5755182018-07-16 10:30:08 -0700191 auto process_discard()
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500192 {
William A. Kennington III49e4bdc2018-06-05 23:28:02 -0700193 int r = _intf->sd_bus_process(_bus.get(), nullptr);
194 if (r < 0)
195 {
196 throw exception::SdBusError(-r, "sd_bus_process discard");
197 }
James Feistb5755182018-07-16 10:30:08 -0700198 return r > 0;
Patrick Williamsc7ba66f2016-10-18 11:30:07 -0500199 }
200
Patrick Williams5b485792016-08-02 07:35:14 -0500201 /** @brief Claim a service name on the dbus.
202 *
203 * @param[in] service - The service name to claim.
204 */
205 void request_name(const char* service)
206 {
Waqar Hameed841d8d32018-10-04 13:35:43 +0200207 int r = _intf->sd_bus_request_name(_bus.get(), service, 0);
208 if (r < 0)
209 {
210 throw exception::SdBusError(-r, "sd_bus_request_name");
211 }
Patrick Williams5b485792016-08-02 07:35:14 -0500212 }
213
214 /** @brief Create a method_call message.
215 *
216 * @param[in] service - The service to call.
217 * @param[in] objpath - The object's path for the call.
218 * @param[in] interf - The object's interface to call.
219 * @param[in] method - The object's method to call.
220 *
221 * @return A newly constructed message.
222 */
223 auto new_method_call(const char* service, const char* objpath,
224 const char* interf, const char* method)
225 {
226 sd_bus_message* m = nullptr;
William A. Kennington IIIec9236d2018-06-05 23:30:15 -0700227 int r = _intf->sd_bus_message_new_method_call(_bus.get(), &m, service,
228 objpath, interf, method);
229 if (r < 0)
230 {
231 throw exception::SdBusError(-r, "sd_bus_message_new_method_call");
232 }
Patrick Williams5b485792016-08-02 07:35:14 -0500233
Patrick Williams10d7aa12021-11-19 11:36:18 -0600234 return message_t(m, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500235 }
236
Patrick Williams20d82462016-10-18 08:01:33 -0500237 /** @brief Create a signal message.
238 *
239 * @param[in] objpath - The object's path for the signal.
240 * @param[in] interf - The object's interface for the signal.
241 * @param[in] member - The signal name.
242 *
243 * @return A newly constructed message.
244 */
245 auto new_signal(const char* objpath, const char* interf, const char* member)
246 {
247 sd_bus_message* m = nullptr;
William A. Kennington IIIec9236d2018-06-05 23:30:15 -0700248 int r = _intf->sd_bus_message_new_signal(_bus.get(), &m, objpath,
249 interf, member);
250 if (r < 0)
251 {
252 throw exception::SdBusError(-r, "sd_bus_message_new_signal");
253 }
Patrick Williams20d82462016-10-18 08:01:33 -0500254
Patrick Williams10d7aa12021-11-19 11:36:18 -0600255 return message_t(m, _intf, std::false_type());
Patrick Williams20d82462016-10-18 08:01:33 -0500256 }
257
Patrick Williams5b485792016-08-02 07:35:14 -0500258 /** @brief Perform a message call.
William A. Kennington III079fb852018-10-12 13:36:31 -0700259 * Errors generated by this call come from underlying dbus
260 * related errors *AND* from any method call that results
261 * in a METHOD_ERROR. This means you do not need to check
262 * is_method_error() on the returned message.
Patrick Williams5b485792016-08-02 07:35:14 -0500263 *
264 * @param[in] m - The method_call message.
265 * @param[in] timeout_us - The timeout for the method call.
266 *
267 * @return The response message.
268 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600269 auto call(message_t& m, uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500270 {
William A. Kennington III55d66862018-05-29 17:13:35 -0700271 sd_bus_error error = SD_BUS_ERROR_NULL;
Patrick Williams5b485792016-08-02 07:35:14 -0500272 sd_bus_message* reply = nullptr;
Brad Bishopb4cc7d72018-12-06 15:27:48 -0500273 int r =
274 _intf->sd_bus_call(_bus.get(), m.get(), timeout_us, &error, &reply);
William A. Kennington III55d66862018-05-29 17:13:35 -0700275 if (r < 0)
276 {
William A. Kennington III68cb1702018-06-22 19:35:48 -0700277 throw exception::SdBusError(&error, "sd_bus_call");
William A. Kennington III55d66862018-05-29 17:13:35 -0700278 }
Patrick Williams5b485792016-08-02 07:35:14 -0500279
Patrick Williams10d7aa12021-11-19 11:36:18 -0600280 return message_t(reply, _intf, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500281 }
Patrick Williams10d7aa12021-11-19 11:36:18 -0600282 auto call(message_t& m, std::optional<SdBusDuration> timeout = std::nullopt)
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800283 {
284 return call(m, timeout ? timeout->count() : 0);
285 }
Patrick Williams5b485792016-08-02 07:35:14 -0500286
287 /** @brief Perform a message call, ignoring the reply.
288 *
289 * @param[in] m - The method_call message.
290 * @param[in] timeout_us - The timeout for the method call.
291 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600292 void call_noreply(message_t& m, uint64_t timeout_us)
Patrick Williams5b485792016-08-02 07:35:14 -0500293 {
William A. Kennington III55d66862018-05-29 17:13:35 -0700294 sd_bus_error error = SD_BUS_ERROR_NULL;
295 int r = _intf->sd_bus_call(_bus.get(), m.get(), timeout_us, &error,
296 nullptr);
297 if (r < 0)
298 {
William A. Kennington III68cb1702018-06-22 19:35:48 -0700299 throw exception::SdBusError(&error, "sd_bus_call noreply");
William A. Kennington III55d66862018-05-29 17:13:35 -0700300 }
Patrick Williams5b485792016-08-02 07:35:14 -0500301 }
Patrick Williams10d7aa12021-11-19 11:36:18 -0600302 auto call_noreply(message_t& m,
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800303 std::optional<SdBusDuration> timeout = std::nullopt)
304 {
305 return call_noreply(m, timeout ? timeout->count() : 0);
306 }
Patrick Williams5b485792016-08-02 07:35:14 -0500307
William A. Kennington III5b701c62018-09-11 00:36:30 -0700308 /** @brief Perform a message call, ignoring the reply and any errors
309 * in the dbus stack.
310 *
311 * @param[in] m - The method_call message.
312 * @param[in] timeout_us - The timeout for the method call.
313 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600314 void call_noreply_noerror(message_t& m, uint64_t timeout_us)
William A. Kennington III5b701c62018-09-11 00:36:30 -0700315 {
316 try
317 {
318 call_noreply(m, timeout_us);
319 }
Patrick Williamsb4667652021-10-06 12:16:17 -0500320 catch (const exception::SdBusError&)
William A. Kennington III5b701c62018-09-11 00:36:30 -0700321 {
322 // Intentionally ignoring these sd_bus errors
323 }
324 }
Patrick Williams68052842020-05-15 11:29:10 -0500325 auto call_noreply_noerror(
Patrick Williams10d7aa12021-11-19 11:36:18 -0600326 message_t& m, std::optional<SdBusDuration> timeout = std::nullopt)
William A. Kennington IIIb5a84462019-03-06 16:46:57 -0800327 {
328 return call_noreply_noerror(m, timeout ? timeout->count() : 0);
329 }
William A. Kennington III5b701c62018-09-11 00:36:30 -0700330
Adriana Kobylakc5496772017-01-04 09:57:23 -0600331 /** @brief Get the bus unique name. Ex: ":1.11".
Patrick Ventureff095682018-04-13 20:54:32 -0700332 *
333 * @return The bus unique name.
334 */
Adriana Kobylakc5496772017-01-04 09:57:23 -0600335 auto get_unique_name()
336 {
337 const char* unique = nullptr;
Patrick Ventureff095682018-04-13 20:54:32 -0700338 _intf->sd_bus_get_unique_name(_bus.get(), &unique);
Adriana Kobylakc5496772017-01-04 09:57:23 -0600339 return std::string(unique);
340 }
341
Brad Bishopb4cc7d72018-12-06 15:27:48 -0500342 auto get_fd()
343 {
William A. Kennington IIIcb582e02018-06-28 18:01:01 -0700344 return _intf->sd_bus_get_fd(_bus.get());
James Feist284a0f92018-04-05 15:28:16 -0700345 }
346
Yi Li8ac39ee2017-01-16 16:21:51 +0800347 /** @brief Attach the bus with a sd-event event loop object.
348 *
349 * @param[in] event - sd_event object.
350 * @param[in] priority - priority of bus event source.
351 */
352 void attach_event(sd_event* event, int priority)
353 {
Patrick Ventureff095682018-04-13 20:54:32 -0700354 _intf->sd_bus_attach_event(_bus.get(), event, priority);
Yi Li8ac39ee2017-01-16 16:21:51 +0800355 }
356
357 /** @brief Detach the bus from its sd-event event loop object */
358 void detach_event()
359 {
Patrick Ventureff095682018-04-13 20:54:32 -0700360 _intf->sd_bus_detach_event(_bus.get());
Yi Li8ac39ee2017-01-16 16:21:51 +0800361 }
362
363 /** @brief Get the sd-event event loop object of the bus */
364 auto get_event()
365 {
Patrick Ventureff095682018-04-13 20:54:32 -0700366 return _intf->sd_bus_get_event(_bus.get());
Yi Li8ac39ee2017-01-16 16:21:51 +0800367 }
368
Brad Bishopd2945572017-02-15 23:40:15 -0500369 /** @brief Wrapper for sd_bus_emit_interfaces_added_strv
370 *
371 * In general the similarly named server::object::object API should
372 * be used to manage emission of ObjectManager signals in favor
373 * of this one. Provided here for complex usage scenarios.
374 *
375 * @param[in] path - The path to forward.
376 * @param[in] ifaces - The interfaces to forward.
377 */
378 void emit_interfaces_added(const char* path,
Patrick Williams32ffb032020-10-12 12:17:48 -0500379 const std::vector<std::string>& ifaces);
Brad Bishopd2945572017-02-15 23:40:15 -0500380
381 /** @brief Wrapper for sd_bus_emit_interfaces_removed_strv
382 *
383 * In general the similarly named server::object::object API should
384 * be used to manage emission of ObjectManager signals in favor
385 * of this one. Provided here for complex usage scenarios.
386 *
387 * @param[in] path - The path to forward.
388 * @param[in] ifaces - The interfaces to forward.
389 */
390 void emit_interfaces_removed(const char* path,
Patrick Williams32ffb032020-10-12 12:17:48 -0500391 const std::vector<std::string>& ifaces);
Brad Bishopd2945572017-02-15 23:40:15 -0500392
Brad Bishop9a0baf52017-02-03 20:05:22 -0500393 /** @brief Wrapper for sd_bus_emit_object_added
394 *
395 * In general the similarly named server::object::object API should
396 * be used to manage emission of ObjectManager signals in favor
397 * of this one. Provided here for complex usage scenarios.
398 *
399 * @param[in] path - The path to forward to sd_bus_emit_object_added
400 */
401 void emit_object_added(const char* path)
402 {
Patrick Ventureff095682018-04-13 20:54:32 -0700403 _intf->sd_bus_emit_object_added(_bus.get(), path);
Brad Bishop9a0baf52017-02-03 20:05:22 -0500404 }
405
406 /** @brief Wrapper for sd_bus_emit_object_removed
407 *
408 * In general the similarly named server::object::object API should
409 * be used to manage emission of ObjectManager signals in favor
410 * of this one. Provided here for complex usage scenarios.
411 *
412 * @param[in] path - The path to forward to sd_bus_emit_object_removed
413 */
414 void emit_object_removed(const char* path)
415 {
Patrick Ventureff095682018-04-13 20:54:32 -0700416 _intf->sd_bus_emit_object_removed(_bus.get(), path);
Brad Bishop9a0baf52017-02-03 20:05:22 -0500417 }
418
Patrick Williamsb4041d42017-04-27 21:49:00 -0500419 /** @brief Wrapper for sd_bus_list_names.
420 *
421 * @return A vector of strings containing the 'acquired' names from
422 * sd_bus_list_names.
423 */
424 auto list_names_acquired()
425 {
426 char** names = nullptr;
427
Patrick Ventureff095682018-04-13 20:54:32 -0700428 _intf->sd_bus_list_names(_bus.get(), &names, nullptr);
Patrick Williamsb4041d42017-04-27 21:49:00 -0500429
430 std::vector<std::string> result;
Patrick Ventureff095682018-04-13 20:54:32 -0700431 for (auto ptr = names; ptr && *ptr; ++ptr)
Patrick Williamsb4041d42017-04-27 21:49:00 -0500432 {
433 result.push_back(*ptr);
434 free(*ptr);
435 }
436 free(names);
437
438 return result;
439 }
440
Patrick Ventureb9a1e192018-04-16 09:40:21 -0700441 /** @brief Get the SdBusInterface used by this bus.
442 *
443 * @return A pointer to the SdBusInterface used by this bus.
444 */
445 sdbusplus::SdBusInterface* getInterface()
446 {
447 return _intf;
448 }
449
Patrick Williams66492212021-11-19 16:49:28 -0600450 friend struct details::bus_friend;
Patrick Williams13f1ef72016-10-17 14:09:33 -0500451
James Feist284a0f92018-04-05 15:28:16 -0700452 protected:
Patrick Williams66492212021-11-19 16:49:28 -0600453 busp_t get() noexcept
Patrick Ventureff095682018-04-13 20:54:32 -0700454 {
455 return _bus.get();
456 }
457 sdbusplus::SdBusInterface* _intf;
458 details::bus _bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500459};
460
Patrick Ventureff095682018-04-13 20:54:32 -0700461inline bus::bus(busp_t b, sdbusplus::SdBusInterface* intf) :
Brad Bishop75834602018-12-11 08:42:53 -0500462 _intf(intf), _bus(_intf->sd_bus_ref(b), details::BusDeleter(intf))
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500463{
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500464 // Emitting object added causes a message to get the properties
465 // which can trigger a 'transaction' in the server bindings. If
466 // the bus isn't up far enough, this causes an assert deep in
467 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
468 // enough to avoid the assert.
469 if (b != nullptr)
470 {
471 get_unique_name();
472 }
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500473}
474
Brad Bishop75834602018-12-11 08:42:53 -0500475inline bus::bus(busp_t b) :
476 _intf(&sdbus_impl),
477 _bus(_intf->sd_bus_ref(b), details::BusDeleter(&sdbus_impl))
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600478{
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600479 // Emitting object added causes a message to get the properties
480 // which can trigger a 'transaction' in the server bindings. If
481 // the bus isn't up far enough, this causes an assert deep in
482 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
483 // enough to avoid the assert.
484 if (b != nullptr)
485 {
486 get_unique_name();
487 }
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600488}
489
Brad Bishop75834602018-12-11 08:42:53 -0500490inline bus::bus(busp_t b, std::false_type) :
491 _intf(&sdbus_impl), _bus(b, details::BusDeleter(&sdbus_impl))
Patrick Ventureff095682018-04-13 20:54:32 -0700492{
Patrick Ventureff095682018-04-13 20:54:32 -0700493 // Emitting object added causes a message to get the properties
494 // which can trigger a 'transaction' in the server bindings. If
495 // the bus isn't up far enough, this causes an assert deep in
496 // sd-bus code. Get the 'unique_name' to ensure the bus is up far
497 // enough to avoid the assert.
498 if (b != nullptr)
499 {
500 get_unique_name();
501 }
Patrick Ventureff095682018-04-13 20:54:32 -0700502}
Patrick Williamsbee1a6a2017-02-16 16:06:51 -0600503
Vernon Mauery8ca60252018-11-08 14:55:34 -0800504/* Create a new default connection: system bus if root, session bus if user */
Brad Bishopaed81792016-10-12 08:40:34 -0400505inline bus new_default()
Patrick Williams5b485792016-08-02 07:35:14 -0500506{
507 sd_bus* b = nullptr;
Vernon Mauery8ca60252018-11-08 14:55:34 -0800508 sd_bus_default(&b);
Patrick Williamsba6f50c2017-04-18 11:38:30 -0500509 return bus(b, std::false_type());
Patrick Williams5b485792016-08-02 07:35:14 -0500510}
511
Vernon Mauery8ca60252018-11-08 14:55:34 -0800512/* Create a new default connection to the session bus */
513inline bus new_default_user()
514{
515 sd_bus* b = nullptr;
516 sd_bus_default_user(&b);
517 return bus(b, std::false_type());
518}
519
520/* Create a new default connection to the system bus */
521inline bus new_default_system()
522{
523 sd_bus* b = nullptr;
524 sd_bus_default_system(&b);
525 return bus(b, std::false_type());
526}
527
528/* WARNING: THESE ARE NOT THE FUNCTIONS YOU ARE LOOKING FOR! */
William A. Kennington III34fdbf32018-12-19 17:33:42 -0800529inline bus new_bus()
530{
531 sd_bus* b = nullptr;
532 sd_bus_open(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800533 bus bus(b, std::false_type());
534 bus.set_should_close(true);
535 return bus;
William A. Kennington III34fdbf32018-12-19 17:33:42 -0800536}
537
Brad Bishopaed81792016-10-12 08:40:34 -0400538inline bus new_user()
Patrick Williams5b485792016-08-02 07:35:14 -0500539{
540 sd_bus* b = nullptr;
541 sd_bus_open_user(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800542 bus bus(b, std::false_type());
543 bus.set_should_close(true);
544 return bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500545}
546
Brad Bishopaed81792016-10-12 08:40:34 -0400547inline bus new_system()
Patrick Williams5b485792016-08-02 07:35:14 -0500548{
549 sd_bus* b = nullptr;
550 sd_bus_open_system(&b);
William A. Kennington III062205d2018-12-19 17:34:13 -0800551 bus bus(b, std::false_type());
552 bus.set_should_close(true);
553 return bus;
Patrick Williams5b485792016-08-02 07:35:14 -0500554}
555
Patrick Williams66492212021-11-19 16:49:28 -0600556namespace details
557{
558
559// Some sdbusplus classes need to be able to pass the underlying bus pointer
560// along to sd_bus calls, but we don't want to make it available for everyone.
561// Define a class which can be inherited explicitly (intended for internal users
562// only) to get the underlying bus pointer.
563struct bus_friend
564{
565 static busp_t get_busp(sdbusplus::bus::bus& b) noexcept
566 {
567 return b.get();
568 }
569};
570
571} // namespace details
572
Patrick Williams5b485792016-08-02 07:35:14 -0500573} // namespace bus
574
Patrick Williams0f282c42021-11-19 11:36:18 -0600575using bus_t = bus::bus;
576
Adriana Kobylak63122252017-01-26 15:09:00 -0600577/** @brief Get the dbus bus from the message.
578 *
579 * @return The dbus bus.
580 */
Patrick Williams10d7aa12021-11-19 11:36:18 -0600581inline auto message_t::get_bus() const
Adriana Kobylak63122252017-01-26 15:09:00 -0600582{
583 sd_bus* b = nullptr;
Patrick Venture4c3427c2018-04-13 17:09:55 -0700584 b = _intf->sd_bus_message_get_bus(_msg.get());
Patrick Williams0f282c42021-11-19 11:36:18 -0600585 return bus_t(b, _intf);
Adriana Kobylak63122252017-01-26 15:09:00 -0600586}
587
Patrick Williams5b485792016-08-02 07:35:14 -0500588} // namespace sdbusplus
Patrick Williams0c8136a2021-08-28 14:42:31 -0500589
590#ifdef __clang__
591#pragma clang diagnostic pop
592#endif