blob: 84202447651df926cc120d74921d6c6780334bf2 [file] [log] [blame]
Patrick Williamsebd6b9c2016-10-18 22:14:12 -05001#pragma once
2
Patrick Williamsebd6b9c2016-10-18 22:14:12 -05003#include <sdbusplus/bus.hpp>
Patrick Williams2f7c8872017-05-01 16:27:57 -05004#include <sdbusplus/message.hpp>
Patrick Venture95269db2018-08-31 09:19:17 -07005#include <sdbusplus/slot.hpp>
Patrick Williams127b8ab2020-05-21 15:24:19 -05006
7#include <functional>
8#include <memory>
Patrick Venture95269db2018-08-31 09:19:17 -07009#include <string>
Patrick Williamsebd6b9c2016-10-18 22:14:12 -050010
11namespace sdbusplus
12{
13
Christian Andersenc69def62016-12-20 13:51:52 +010014namespace bus
Patrick Williamsebd6b9c2016-10-18 22:14:12 -050015{
16
17namespace match
18{
19
20struct match
21{
Christian Andersenc69def62016-12-20 13:51:52 +010022 /* Define all of the basic class operations:
23 * Not allowed:
24 * - Default constructor to avoid nullptrs.
25 * - Copy operations due to internal unique_ptr.
26 * Allowed:
27 * - Move operations.
28 * - Destructor.
29 */
Patrick Williamsebd6b9c2016-10-18 22:14:12 -050030 match() = delete;
31 match(const match&) = delete;
32 match& operator=(const match&) = delete;
33 match(match&&) = default;
34 match& operator=(match&&) = default;
35 ~match() = default;
36
37 /** @brief Register a signal match.
38 *
39 * @param[in] bus - The bus to register on.
40 * @param[in] match - The match to register.
41 * @param[in] handler - The callback for matches.
Patrick Williamsb12ca162016-10-19 10:38:19 -050042 * @param[in] context - An optional context to pass to the handler.
Patrick Williamsebd6b9c2016-10-18 22:14:12 -050043 */
44 match(sdbusplus::bus::bus& bus, const char* match,
Andrew Geissler072da3e2018-01-18 07:21:42 -080045 sd_bus_message_handler_t handler, void* context = nullptr) :
46 _slot(nullptr)
Patrick Williamsebd6b9c2016-10-18 22:14:12 -050047 {
48 sd_bus_slot* slot = nullptr;
Patrick Williamsb12ca162016-10-19 10:38:19 -050049 sd_bus_add_match(bus.get(), &slot, match, handler, context);
Patrick Williamsebd6b9c2016-10-18 22:14:12 -050050
51 _slot = decltype(_slot){slot};
52 }
Patrick Williamsda25f342017-05-01 18:08:16 -050053 match(sdbusplus::bus::bus& bus, const std::string& _match,
Andrew Geissler072da3e2018-01-18 07:21:42 -080054 sd_bus_message_handler_t handler, void* context = nullptr) :
55 match(bus, _match.c_str(), handler, context)
Patrick Williams127b8ab2020-05-21 15:24:19 -050056 {}
Patrick Williamsebd6b9c2016-10-18 22:14:12 -050057
Patrick Williams2f7c8872017-05-01 16:27:57 -050058 using callback_t = std::function<void(sdbusplus::message::message&)>;
59
60 /** @brief Register a signal match.
61 *
62 * @param[in] bus - The bus to register on.
63 * @param[in] match - The match to register.
64 * @param[in] callback - The callback for matches.
65 */
Andrew Geissler072da3e2018-01-18 07:21:42 -080066 match(sdbusplus::bus::bus& bus, const char* match, callback_t callback) :
67 _slot(nullptr),
68 _callback(std::make_unique<callback_t>(std::move(callback)))
Patrick Williams2f7c8872017-05-01 16:27:57 -050069 {
70 sd_bus_slot* slot = nullptr;
71 sd_bus_add_match(bus.get(), &slot, match, callCallback,
72 _callback.get());
73
74 _slot = decltype(_slot){slot};
75 }
Patrick Williamsda25f342017-05-01 18:08:16 -050076 match(sdbusplus::bus::bus& bus, const std::string& _match,
Andrew Geissler072da3e2018-01-18 07:21:42 -080077 callback_t callback) :
78 match(bus, _match.c_str(), callback)
Patrick Williams127b8ab2020-05-21 15:24:19 -050079 {}
Patrick Williams2f7c8872017-05-01 16:27:57 -050080
Andrew Geissler072da3e2018-01-18 07:21:42 -080081 private:
82 slot::slot _slot;
83 std::unique_ptr<callback_t> _callback = nullptr;
Patrick Williams2f7c8872017-05-01 16:27:57 -050084
Patrick Williams78b78032020-05-20 10:32:05 -050085 static int callCallback(sd_bus_message* m, void* context,
86 sd_bus_error* /*e*/)
Andrew Geissler072da3e2018-01-18 07:21:42 -080087 {
88 auto c = static_cast<callback_t*>(context);
89 message::message message{m};
Patrick Williams2f7c8872017-05-01 16:27:57 -050090
Andrew Geissler072da3e2018-01-18 07:21:42 -080091 (*c)(message);
Patrick Williams2f7c8872017-05-01 16:27:57 -050092
Andrew Geissler072da3e2018-01-18 07:21:42 -080093 return 0;
94 }
Patrick Williamsebd6b9c2016-10-18 22:14:12 -050095};
96
Patrick Williamsa85fdff2017-05-01 17:52:15 -050097/** Utilities for defining match rules based on the DBus specification */
98namespace rules
99{
100
101using namespace std::string_literals;
102
103namespace type
104{
105
Andrew Geissler072da3e2018-01-18 07:21:42 -0800106inline auto signal()
107{
108 return "type='signal',"s;
109}
110inline auto method()
111{
112 return "type='method',"s;
113}
114inline auto method_return()
115{
116 return "type='method_return',"s;
117}
118inline auto error()
119{
120 return "type='error',"s;
121}
Patrick Williamsa85fdff2017-05-01 17:52:15 -0500122
123} // namespace type
124
Andrew Geissler072da3e2018-01-18 07:21:42 -0800125inline auto sender(const std::string& s)
126{
127 return "sender='"s + s + "',";
128}
Patrick Williamsa85fdff2017-05-01 17:52:15 -0500129inline auto interface(const std::string& s)
Andrew Geissler072da3e2018-01-18 07:21:42 -0800130{
131 return "interface='"s + s + "',";
132}
133inline auto member(const std::string& s)
134{
135 return "member='"s + s + "',";
136}
137inline auto path(const std::string& s)
138{
139 return "path='"s + s + "',";
140}
Patrick Williamsa85fdff2017-05-01 17:52:15 -0500141inline auto path_namespace(const std::string& s)
Andrew Geissler072da3e2018-01-18 07:21:42 -0800142{
143 return "path_namespace='"s + s + "',";
144}
Patrick Williamsa85fdff2017-05-01 17:52:15 -0500145inline auto destination(const std::string& s)
Andrew Geissler072da3e2018-01-18 07:21:42 -0800146{
147 return "destination='"s + s + "',";
148}
Patrick Williamsa85fdff2017-05-01 17:52:15 -0500149inline auto argN(size_t n, const std::string& s)
Andrew Geissler072da3e2018-01-18 07:21:42 -0800150{
151 return "arg"s + std::to_string(n) + "='"s + s + "',";
152}
Patrick Williamsa85fdff2017-05-01 17:52:15 -0500153inline auto argNpath(size_t n, const std::string& s)
Andrew Geissler072da3e2018-01-18 07:21:42 -0800154{
155 return "arg"s + std::to_string(n) + "path='"s + s + "',";
156}
Patrick Williamsa85fdff2017-05-01 17:52:15 -0500157inline auto arg0namespace(const std::string& s)
Andrew Geissler072da3e2018-01-18 07:21:42 -0800158{
159 return "arg0namespace='"s + s + "',";
160}
161inline auto eavesdrop()
162{
163 return "eavesdrop='true',"s;
164}
Patrick Williamsa85fdff2017-05-01 17:52:15 -0500165
166inline auto nameOwnerChanged()
167{
168 return "type='signal',"
169 "sender='org.freedesktop.DBus',"
170 "member='NameOwnerChanged',"s;
171}
172
Patrick Williams5c48c8b2017-05-30 16:12:05 -0500173inline auto interfacesAdded()
174{
175 return "type='signal',"
176 "interface='org.freedesktop.DBus.ObjectManager',"
177 "member='InterfacesAdded',"s;
178}
179
Brad Bishop82f083d2017-06-19 16:15:08 -0400180inline auto interfacesRemoved()
181{
182 return "type='signal',"
183 "interface='org.freedesktop.DBus.ObjectManager',"
184 "member='InterfacesRemoved',"s;
185}
186
187inline auto interfacesAdded(const std::string& p)
188{
189 return interfacesAdded() + path(p);
190}
191
192inline auto interfacesRemoved(const std::string& p)
193{
194 return interfacesRemoved() + path(p);
195}
196
197inline auto propertiesChanged(const std::string& p, const std::string& i)
198{
Andrew Geissler072da3e2018-01-18 07:21:42 -0800199 return type::signal() + path(p) + member("PropertiesChanged"s) +
200 interface("org.freedesktop.DBus.Properties"s) + argN(0, i);
Brad Bishop82f083d2017-06-19 16:15:08 -0400201}
202
Matthew Bartha3c58a92017-11-14 13:43:21 -0600203/**
204 * @brief Constructs a NameOwnerChanged match string for a service name
205 *
206 * @param[in] s - Service name
207 *
208 * @return NameOwnerChanged match string for a service name
209 */
210inline auto nameOwnerChanged(const std::string& s)
211{
212 return nameOwnerChanged() + argN(0, s);
213}
214
Patrick Williamsa85fdff2017-05-01 17:52:15 -0500215} // namespace rules
Patrick Williamsebd6b9c2016-10-18 22:14:12 -0500216} // namespace match
217
218using match_t = match::match;
219
Christian Andersenc69def62016-12-20 13:51:52 +0100220} // namespace bus
Patrick Williamsebd6b9c2016-10-18 22:14:12 -0500221} // namespace sdbusplus