blob: 90c10247bd031fc6c1c63b169f371c888dd233c5 [file] [log] [blame]
Brad Bishop3d57f502016-10-19 12:18:41 -04001#pragma once
2
3#include <utility>
4#include <memory>
5#include <sdbusplus/message.hpp>
Brad Bishop65ffffa2016-11-29 12:31:31 -05006#include "utils.hpp"
Brad Bishop3d57f502016-10-19 12:18:41 -04007
8namespace phosphor
9{
10namespace inventory
11{
12namespace manager
13{
Brad Bishopc0eae112016-10-19 21:59:47 -040014
15class Manager;
Brad Bishop65ffffa2016-11-29 12:31:31 -050016namespace details
17{
Brad Bishop7b337772017-01-12 16:11:24 -050018using FilterBase = holder::CallableBase <
19 bool, sdbusplus::message::message&, Manager& >;
Brad Bishop65ffffa2016-11-29 12:31:31 -050020using FilterBasePtr = std::shared_ptr<FilterBase>;
21template <typename T>
Brad Bishop7b337772017-01-12 16:11:24 -050022using Filter = holder::CallableHolder <
23 T, bool, sdbusplus::message::message&, Manager& >;
Brad Bishop65ffffa2016-11-29 12:31:31 -050024
Brad Bishop4f20a3e2016-11-29 15:21:46 -050025/** @struct Event
26 * @brief Event object interface.
27 */
28struct Event
29{
30 enum class Type
31 {
32 DBUS_SIGNAL,
33 };
34
35 virtual ~Event() = default;
36 Event(const Event&) = default;
37 Event& operator=(const Event&) = default;
38 Event(Event&&) = default;
39 Event& operator=(Event&&) = default;
40 explicit Event(Type t) : type(t) {}
41
42 Type type;
43};
44
45using EventBasePtr = std::shared_ptr<Event>;
46
47/** @struct DbusSignal
48 * @brief DBus signal event.
49 *
50 * DBus signal events are an association of a match signature
51 * and filtering function object.
52 */
53struct DbusSignal final :
54 public Event,
Brad Bishop7b337772017-01-12 16:11:24 -050055 public std::tuple<const char*, FilterBasePtr>
Brad Bishop4f20a3e2016-11-29 15:21:46 -050056{
57 virtual ~DbusSignal() = default;
58 DbusSignal(const DbusSignal&) = default;
Brad Bishop7b337772017-01-12 16:11:24 -050059 DbusSignal& operator=(const DbusSignal&) = delete;
Brad Bishop4f20a3e2016-11-29 15:21:46 -050060 DbusSignal(DbusSignal&&) = default;
61 DbusSignal& operator=(DbusSignal&&) = default;
62
63 /** @brief Import from signature and filter constructor.
64 *
65 * @param[in] sig - The DBus match signature.
66 * @param[in] filter - A DBus signal match callback filtering function.
67 */
Brad Bishop7b337772017-01-12 16:11:24 -050068 DbusSignal(const char* sig, FilterBasePtr filter) :
Brad Bishop4f20a3e2016-11-29 15:21:46 -050069 Event(Type::DBUS_SIGNAL),
Brad Bishop7b337772017-01-12 16:11:24 -050070 std::tuple<const char*, FilterBasePtr>(
71 sig, std::move(filter)) {}
Brad Bishop4f20a3e2016-11-29 15:21:46 -050072};
73
Brad Bishop65ffffa2016-11-29 12:31:31 -050074/** @brief make_filter
75 *
76 * Adapt a filter function object.
77 *
78 * @param[in] filter - The filter being adapted.
79 * @returns - The adapted filter.
80 *
81 * @tparam T - The type of the filter being adapted.
82 */
83template <typename T>
84auto make_filter(T&& filter)
85{
86 return Filter<T>::template make_shared<Filter<T>>(
87 std::forward<T>(filter));
88}
89} // namespace details
90
Brad Bishop3d57f502016-10-19 12:18:41 -040091namespace filters
92{
93namespace details
94{
Brad Bishopbf5aa9c2016-10-19 21:19:04 -040095namespace property_condition
96{
97
98/** @struct PropertyCondition
99 * @brief Match filter functor that tests a property value.
100 *
101 * @tparam T - The type of the property being tested.
102 * @tparam U - The type of the condition checking functor.
103 */
104template <typename T, typename U>
105struct PropertyCondition
106{
Brad Bishop7b337772017-01-12 16:11:24 -0500107 PropertyCondition() = delete;
108 ~PropertyCondition() = default;
109 PropertyCondition(const PropertyCondition&) = default;
110 PropertyCondition& operator=(const PropertyCondition&) = delete;
111 PropertyCondition(PropertyCondition&&) = default;
112 PropertyCondition& operator=(PropertyCondition&&) = default;
113 PropertyCondition(const char* iface, const char* property, U&& condition) :
114 _iface(iface),
115 _property(property),
116 _condition(std::forward<U>(condition)) { }
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400117
Brad Bishop7b337772017-01-12 16:11:24 -0500118 /** @brief Test a property value.
119 *
120 * Extract the property from the PropertiesChanged
121 * message and run the condition test.
122 */
123 bool operator()(sdbusplus::message::message& msg, Manager&) const
124 {
125 std::map <
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400126 std::string,
Brad Bishop7b337772017-01-12 16:11:24 -0500127 sdbusplus::message::variant<T >> properties;
128 const char* iface = nullptr;
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400129
Brad Bishop7b337772017-01-12 16:11:24 -0500130 msg.read(iface);
131 if (strcmp(iface, _iface))
132 {
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400133 return false;
Brad Bishop7b337772017-01-12 16:11:24 -0500134 }
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400135
Brad Bishop7b337772017-01-12 16:11:24 -0500136 msg.read(properties);
137 auto it = properties.find(_property);
138 if (it == properties.cend())
139 {
140 return false;
141 }
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400142
Brad Bishop7b337772017-01-12 16:11:24 -0500143 return _condition(it->second.template get<T>());
144 }
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400145
146 private:
Brad Bishop7b337772017-01-12 16:11:24 -0500147 const char* _iface;
148 const char* _property;
149 U _condition;
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400150};
151
152} // namespace property_condition
Brad Bishop3d57f502016-10-19 12:18:41 -0400153} // namespace details
154
155/** @brief The default filter. */
Brad Bishop7b337772017-01-12 16:11:24 -0500156inline bool none(sdbusplus::message::message&, Manager&) noexcept
Brad Bishop3d57f502016-10-19 12:18:41 -0400157{
158 return true;
159}
160
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400161/** @brief Implicit type deduction for constructing PropertyCondition. */
162template <typename T>
163auto propertyChangedTo(
Brad Bishop7b337772017-01-12 16:11:24 -0500164 const char* iface,
165 const char* property,
166 T val)
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400167{
Brad Bishop7b337772017-01-12 16:11:24 -0500168 auto condition = [val = std::move(val)](const std::string & arg)
Brad Bishopd1bbf3a2016-12-01 00:03:26 -0500169 {
170 return arg == val;
171 };
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400172 using U = decltype(condition);
173 return details::property_condition::PropertyCondition<T, U>(
Brad Bishop7b337772017-01-12 16:11:24 -0500174 iface, property, std::move(condition));
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400175}
176
Brad Bishop3d57f502016-10-19 12:18:41 -0400177} // namespace filters
178} // namespace manager
179} // namespace inventory
180} // namespace phosphor
181
182// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4