blob: 65eb06a5379a919b69415251bf6728b28a9ab14b [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 Bishopfb083c22017-01-19 09:22:04 -0500143 return _condition(
144 std::forward<T>(it->second.template get<T>()));
Brad Bishop7b337772017-01-12 16:11:24 -0500145 }
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400146
147 private:
Brad Bishop7b337772017-01-12 16:11:24 -0500148 const char* _iface;
149 const char* _property;
150 U _condition;
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400151};
152
153} // namespace property_condition
Brad Bishop3d57f502016-10-19 12:18:41 -0400154} // namespace details
155
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400156/** @brief Implicit type deduction for constructing PropertyCondition. */
157template <typename T>
158auto propertyChangedTo(
Brad Bishop7b337772017-01-12 16:11:24 -0500159 const char* iface,
160 const char* property,
Brad Bishopfb083c22017-01-19 09:22:04 -0500161 T&& val)
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400162{
Brad Bishopfb083c22017-01-19 09:22:04 -0500163 auto condition = [val = std::move(val)](T && arg)
Brad Bishopd1bbf3a2016-12-01 00:03:26 -0500164 {
165 return arg == val;
166 };
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400167 using U = decltype(condition);
168 return details::property_condition::PropertyCondition<T, U>(
Brad Bishop7b337772017-01-12 16:11:24 -0500169 iface, property, std::move(condition));
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400170}
171
Brad Bishop3d57f502016-10-19 12:18:41 -0400172} // namespace filters
173} // namespace manager
174} // namespace inventory
175} // namespace phosphor
176
177// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4