Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 1 | #pragma once |
| 2 | |
| 3 | #include <memory> |
Patrick Williams | 560e5fd | 2017-01-12 10:00:17 -0600 | [diff] [blame] | 4 | #include <type_traits> |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 5 | #include <systemd/sd-bus.h> |
| 6 | #include <sdbusplus/message/append.hpp> |
Patrick Williams | 4fe85a3 | 2016-09-08 15:03:56 -0500 | [diff] [blame] | 7 | #include <sdbusplus/message/read.hpp> |
Patrick Williams | 9db2864 | 2017-01-06 15:55:05 -0600 | [diff] [blame] | 8 | #include <sdbusplus/message/native_types.hpp> |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 9 | #include <sdbusplus/sdbus.hpp> |
| 10 | |
| 11 | extern sdbusplus::SdBusImpl sdbus_impl; |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 12 | |
| 13 | namespace sdbusplus |
| 14 | { |
| 15 | |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 16 | // Forward declare sdbusplus::bus::bus for 'friend'ship. |
| 17 | namespace bus |
| 18 | { |
| 19 | struct bus; |
| 20 | }; |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 21 | |
| 22 | namespace message |
| 23 | { |
| 24 | |
| 25 | using msgp_t = sd_bus_message*; |
| 26 | class message; |
| 27 | |
| 28 | namespace details |
| 29 | { |
| 30 | |
| 31 | /** @brief unique_ptr functor to release a msg reference. */ |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 32 | // TODO(venture): Consider using template <SdBusInterfaceType> for this so that |
| 33 | // it doesn't require creating a specific instance of it, unless that's ok -- |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 34 | struct MsgDeleter |
| 35 | { |
| 36 | void operator()(msgp_t ptr) const |
| 37 | { |
| 38 | sd_bus_message_unref(ptr); |
| 39 | } |
| 40 | }; |
| 41 | |
| 42 | /* @brief Alias 'msg' to a unique_ptr type for auto-release. */ |
| 43 | using msg = std::unique_ptr<sd_bus_message, MsgDeleter>; |
| 44 | |
| 45 | } // namespace details |
| 46 | |
| 47 | /** @class message |
| 48 | * @brief Provides C++ bindings to the sd_bus_message_* class functions. |
| 49 | */ |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 50 | class message |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 51 | { |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 52 | /* Define all of the basic class operations: |
| 53 | * Not allowed: |
| 54 | * - Default constructor to avoid nullptrs. |
| 55 | * - Copy operations due to internal unique_ptr. |
| 56 | * Allowed: |
| 57 | * - Move operations. |
| 58 | * - Destructor. |
| 59 | */ |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 60 | public: |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 61 | message() = delete; |
| 62 | message(const message&) = delete; |
| 63 | message& operator=(const message&) = delete; |
| 64 | message(message&&) = default; |
| 65 | message& operator=(message&&) = default; |
| 66 | ~message() = default; |
| 67 | |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 68 | message(msgp_t m, sdbusplus::SdBusInterface* intf) : |
| 69 | _intf(std::move(intf)), _msg(_intf->sd_bus_message_ref(m)) |
| 70 | { |
| 71 | } |
| 72 | |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 73 | /** @brief Conversion constructor for 'msgp_t'. |
| 74 | * |
Patrick Williams | 560e5fd | 2017-01-12 10:00:17 -0600 | [diff] [blame] | 75 | * Takes increment ref-count of the msg-pointer and release when |
| 76 | * destructed. |
| 77 | */ |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 78 | explicit message(msgp_t m) : message(m, &sdbus_impl) |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 79 | { |
| 80 | } |
Patrick Williams | 560e5fd | 2017-01-12 10:00:17 -0600 | [diff] [blame] | 81 | |
Patrick Venture | ff09568 | 2018-04-13 20:54:32 -0700 | [diff] [blame] | 82 | message(msgp_t m, sdbusplus::SdBusInterface* intf, std::false_type) : |
| 83 | _intf(intf), _msg(m) |
| 84 | { |
| 85 | } |
| 86 | |
Patrick Williams | 560e5fd | 2017-01-12 10:00:17 -0600 | [diff] [blame] | 87 | /** @brief Constructor for 'msgp_t'. |
| 88 | * |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 89 | * Takes ownership of the msg-pointer and releases it when done. |
| 90 | */ |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 91 | message(msgp_t m, std::false_type) : _intf(&sdbus_impl), _msg(m) |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 92 | { |
| 93 | } |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 94 | |
| 95 | /** @brief Release ownership of the stored msg-pointer. */ |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 96 | msgp_t release() |
| 97 | { |
| 98 | return _msg.release(); |
| 99 | } |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 100 | |
Patrick Williams | 4fe85a3 | 2016-09-08 15:03:56 -0500 | [diff] [blame] | 101 | /** @brief Check if message contains a real pointer. (non-nullptr). */ |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 102 | explicit operator bool() const |
| 103 | { |
| 104 | return bool(_msg); |
| 105 | } |
Patrick Williams | 4fe85a3 | 2016-09-08 15:03:56 -0500 | [diff] [blame] | 106 | |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 107 | /** @brief Perform sd_bus_message_append, with automatic type deduction. |
| 108 | * |
| 109 | * @tparam ...Args - Type of items to append to message. |
| 110 | * @param[in] args - Items to append to message. |
| 111 | */ |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 112 | template <typename... Args> void append(Args&&... args) |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 113 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 114 | sdbusplus::message::append(_intf, _msg.get(), |
| 115 | std::forward<Args>(args)...); |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 116 | } |
| 117 | |
Patrick Williams | 4fe85a3 | 2016-09-08 15:03:56 -0500 | [diff] [blame] | 118 | /** @brief Perform sd_bus_message_read, with automatic type deduction. |
| 119 | * |
| 120 | * @tparam ...Args - Type of items to read from message. |
| 121 | * @param[out] args - Items to read from message. |
| 122 | */ |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 123 | template <typename... Args> void read(Args&&... args) |
Patrick Williams | 4fe85a3 | 2016-09-08 15:03:56 -0500 | [diff] [blame] | 124 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 125 | sdbusplus::message::read(_intf, _msg.get(), |
| 126 | std::forward<Args>(args)...); |
Patrick Williams | 4fe85a3 | 2016-09-08 15:03:56 -0500 | [diff] [blame] | 127 | } |
| 128 | |
Adriana Kobylak | 6312225 | 2017-01-26 15:09:00 -0600 | [diff] [blame] | 129 | /** @brief Get the dbus bus from the message. */ |
| 130 | // Forward declare. |
| 131 | auto get_bus(); |
| 132 | |
Patrick Williams | 4fe85a3 | 2016-09-08 15:03:56 -0500 | [diff] [blame] | 133 | /** @brief Get the signature of a message. |
| 134 | * |
| 135 | * @return A [weak] pointer to the signature of the message. |
| 136 | */ |
| 137 | const char* get_signature() |
| 138 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 139 | return _intf->sd_bus_message_get_signature(_msg.get(), true); |
Patrick Williams | 4fe85a3 | 2016-09-08 15:03:56 -0500 | [diff] [blame] | 140 | } |
| 141 | |
Brad Bishop | 61f57a4 | 2017-05-12 13:27:50 -0400 | [diff] [blame] | 142 | /** @brief Get the path of a message. |
| 143 | * |
| 144 | * @return A [weak] pointer to the path of the message. |
| 145 | */ |
| 146 | const char* get_path() |
| 147 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 148 | return _intf->sd_bus_message_get_path(_msg.get()); |
Brad Bishop | 61f57a4 | 2017-05-12 13:27:50 -0400 | [diff] [blame] | 149 | } |
| 150 | |
| 151 | /** @brief Get the interface of a message. |
| 152 | * |
| 153 | * @return A [weak] pointer to the interface of the message. |
| 154 | */ |
| 155 | const char* get_interface() |
| 156 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 157 | return _intf->sd_bus_message_get_interface(_msg.get()); |
Brad Bishop | 61f57a4 | 2017-05-12 13:27:50 -0400 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | /** @brief Get the member of a message. |
| 161 | * |
| 162 | * @return A [weak] pointer to the member of the message. |
| 163 | */ |
| 164 | const char* get_member() |
| 165 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 166 | return _intf->sd_bus_message_get_member(_msg.get()); |
Brad Bishop | 61f57a4 | 2017-05-12 13:27:50 -0400 | [diff] [blame] | 167 | } |
| 168 | |
| 169 | /** @brief Get the destination of a message. |
| 170 | * |
| 171 | * @return A [weak] pointer to the destination of the message. |
| 172 | */ |
| 173 | const char* get_destination() |
| 174 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 175 | return _intf->sd_bus_message_get_destination(_msg.get()); |
Brad Bishop | 61f57a4 | 2017-05-12 13:27:50 -0400 | [diff] [blame] | 176 | } |
| 177 | |
| 178 | /** @brief Get the sender of a message. |
| 179 | * |
| 180 | * @return A [weak] pointer to the sender of the message. |
| 181 | */ |
| 182 | const char* get_sender() |
| 183 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 184 | return _intf->sd_bus_message_get_sender(_msg.get()); |
Brad Bishop | 61f57a4 | 2017-05-12 13:27:50 -0400 | [diff] [blame] | 185 | } |
| 186 | |
Christian Andersen | 9b97062 | 2016-12-15 15:05:44 +0100 | [diff] [blame] | 187 | /** @brief Check if message is a method error. |
| 188 | * |
| 189 | * @return True - if message is a method error. |
| 190 | */ |
| 191 | bool is_method_error() |
| 192 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 193 | return _intf->sd_bus_message_is_method_error(_msg.get(), nullptr); |
Christian Andersen | 9b97062 | 2016-12-15 15:05:44 +0100 | [diff] [blame] | 194 | } |
| 195 | |
James Feist | 284a0f9 | 2018-04-05 15:28:16 -0700 | [diff] [blame^] | 196 | /** @brief Get the errno from the message. |
| 197 | * |
| 198 | * @return The errno of the message. |
| 199 | */ |
| 200 | int get_errno() |
| 201 | { |
| 202 | return sd_bus_message_get_errno(_msg.get()); |
| 203 | } |
| 204 | |
Adriana Kobylak | b6dcf97 | 2017-01-04 12:14:04 -0600 | [diff] [blame] | 205 | /** @brief Get the transaction cookie of a message. |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 206 | * |
| 207 | * @return The transaction cookie of a message. |
| 208 | */ |
Adriana Kobylak | b6dcf97 | 2017-01-04 12:14:04 -0600 | [diff] [blame] | 209 | auto get_cookie() |
| 210 | { |
| 211 | uint64_t cookie; |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 212 | _intf->sd_bus_message_get_cookie(_msg.get(), &cookie); |
Adriana Kobylak | b6dcf97 | 2017-01-04 12:14:04 -0600 | [diff] [blame] | 213 | return cookie; |
| 214 | } |
| 215 | |
Patrick Williams | 4fe85a3 | 2016-09-08 15:03:56 -0500 | [diff] [blame] | 216 | /** @brief Check if message is a method call for an interface/method. |
| 217 | * |
| 218 | * @param[in] interface - The interface to match. |
| 219 | * @param[in] method - The method to match. |
| 220 | * |
| 221 | * @return True - if message is a method call for interface/method. |
| 222 | */ |
| 223 | bool is_method_call(const char* interface, const char* method) |
| 224 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 225 | return _intf->sd_bus_message_is_method_call(_msg.get(), interface, |
| 226 | method); |
Patrick Williams | 4fe85a3 | 2016-09-08 15:03:56 -0500 | [diff] [blame] | 227 | } |
| 228 | |
Patrick Williams | 20d8246 | 2016-10-18 08:01:33 -0500 | [diff] [blame] | 229 | /** @brief Check if message is a signal for an interface/member. |
| 230 | * |
| 231 | * @param[in] interface - The interface to match. |
| 232 | * @param[in] member - The member to match. |
| 233 | */ |
| 234 | bool is_signal(const char* interface, const char* member) |
| 235 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 236 | return _intf->sd_bus_message_is_signal(_msg.get(), interface, member); |
Patrick Williams | 20d8246 | 2016-10-18 08:01:33 -0500 | [diff] [blame] | 237 | } |
| 238 | |
Patrick Williams | 2a47ecd | 2016-10-16 17:16:58 -0500 | [diff] [blame] | 239 | /** @brief Create a 'method_return' type message from an existing message. |
| 240 | * |
| 241 | * @return method-return message. |
| 242 | */ |
| 243 | message new_method_return() |
| 244 | { |
| 245 | msgp_t reply = nullptr; |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 246 | _intf->sd_bus_message_new_method_return(this->get(), &reply); |
Patrick Williams | 2a47ecd | 2016-10-16 17:16:58 -0500 | [diff] [blame] | 247 | |
Patrick Williams | 560e5fd | 2017-01-12 10:00:17 -0600 | [diff] [blame] | 248 | return message(reply, std::false_type()); |
Patrick Williams | 2a47ecd | 2016-10-16 17:16:58 -0500 | [diff] [blame] | 249 | } |
| 250 | |
Patrick Williams | 425dc9b | 2016-10-17 16:50:53 -0500 | [diff] [blame] | 251 | /** @brief Perform a 'method-return' response call. */ |
| 252 | void method_return() |
| 253 | { |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 254 | auto b = _intf->sd_bus_message_get_bus(this->get()); |
| 255 | _intf->sd_bus_send(b, this->get(), nullptr); |
Patrick Williams | 425dc9b | 2016-10-17 16:50:53 -0500 | [diff] [blame] | 256 | } |
| 257 | |
Patrick Williams | cfea00a | 2016-10-18 11:11:21 -0500 | [diff] [blame] | 258 | /** @brief Perform a 'signal-send' call. */ |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 259 | void signal_send() |
| 260 | { |
| 261 | method_return(); |
| 262 | } |
Patrick Williams | cfea00a | 2016-10-18 11:11:21 -0500 | [diff] [blame] | 263 | |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 264 | friend struct sdbusplus::bus::bus; |
| 265 | |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 266 | /** @brief Get a pointer to the owned 'msgp_t'. */ |
| 267 | msgp_t get() |
| 268 | { |
| 269 | return _msg.get(); |
| 270 | } |
James Feist | 284a0f9 | 2018-04-05 15:28:16 -0700 | [diff] [blame^] | 271 | |
| 272 | private: |
Patrick Venture | 4c3427c | 2018-04-13 17:09:55 -0700 | [diff] [blame] | 273 | sdbusplus::SdBusInterface* _intf; |
Andrew Geissler | 072da3e | 2018-01-18 07:21:42 -0800 | [diff] [blame] | 274 | details::msg _msg; |
Patrick Williams | 5acb549 | 2016-09-02 15:14:16 -0500 | [diff] [blame] | 275 | }; |
| 276 | |
| 277 | } // namespace message |
| 278 | |
| 279 | } // namespace sdbusplus |