blob: 80fcdaeb79453094006bccb3edf599d5f9497d19 [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 <
Brad Bishop23719002017-01-24 21:08:46 -050019 bool, sdbusplus::bus::bus&, 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 <
Brad Bishop23719002017-01-24 21:08:46 -050023 T, bool, sdbusplus::bus::bus&, 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 Bishop064c94a2017-01-21 21:33:30 -050055 public std::tuple<const char*, std::vector<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 Bishop064c94a2017-01-21 21:33:30 -050068 DbusSignal(const char* sig, const std::vector<FilterBasePtr>& filters) :
Brad Bishop4f20a3e2016-11-29 15:21:46 -050069 Event(Type::DBUS_SIGNAL),
Brad Bishop064c94a2017-01-21 21:33:30 -050070 std::tuple<const char*, std::vector<FilterBasePtr>>(
71 sig, std::move(filters)) {}
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
Brad Bishop143522e2017-01-19 09:12:54 -050098/** @struct PropertyChangedCondition
Brad Bishopbf5aa9c2016-10-19 21:19:04 -040099 * @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>
Brad Bishop143522e2017-01-19 09:12:54 -0500105struct PropertyChangedCondition
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400106{
Brad Bishop143522e2017-01-19 09:12:54 -0500107 PropertyChangedCondition() = delete;
108 ~PropertyChangedCondition() = default;
109 PropertyChangedCondition(const PropertyChangedCondition&) = default;
110 PropertyChangedCondition& operator=(const PropertyChangedCondition&) = delete;
111 PropertyChangedCondition(PropertyChangedCondition&&) = default;
112 PropertyChangedCondition& operator=(PropertyChangedCondition&&) = default;
113 PropertyChangedCondition(const char* iface, const char* property,
114 U&& condition) :
Brad Bishop7b337772017-01-12 16:11:24 -0500115 _iface(iface),
116 _property(property),
117 _condition(std::forward<U>(condition)) { }
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400118
Brad Bishop7b337772017-01-12 16:11:24 -0500119 /** @brief Test a property value.
120 *
121 * Extract the property from the PropertiesChanged
122 * message and run the condition test.
123 */
Brad Bishop23719002017-01-24 21:08:46 -0500124 bool operator()(
125 sdbusplus::bus::bus&,
126 sdbusplus::message::message& msg,
127 Manager&) const
Brad Bishop7b337772017-01-12 16:11:24 -0500128 {
129 std::map <
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400130 std::string,
Brad Bishop7b337772017-01-12 16:11:24 -0500131 sdbusplus::message::variant<T >> properties;
132 const char* iface = nullptr;
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400133
Brad Bishop7b337772017-01-12 16:11:24 -0500134 msg.read(iface);
Brad Bishop064c94a2017-01-21 21:33:30 -0500135 if (!iface || strcmp(iface, _iface))
Brad Bishop7b337772017-01-12 16:11:24 -0500136 {
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400137 return false;
Brad Bishop7b337772017-01-12 16:11:24 -0500138 }
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400139
Brad Bishop7b337772017-01-12 16:11:24 -0500140 msg.read(properties);
141 auto it = properties.find(_property);
142 if (it == properties.cend())
143 {
144 return false;
145 }
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400146
Brad Bishopfb083c22017-01-19 09:22:04 -0500147 return _condition(
148 std::forward<T>(it->second.template get<T>()));
Brad Bishop7b337772017-01-12 16:11:24 -0500149 }
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400150
151 private:
Brad Bishop7b337772017-01-12 16:11:24 -0500152 const char* _iface;
153 const char* _property;
154 U _condition;
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400155};
156
157} // namespace property_condition
Brad Bishop3d57f502016-10-19 12:18:41 -0400158} // namespace details
159
Brad Bishop143522e2017-01-19 09:12:54 -0500160/** @brief Implicit type deduction for constructing PropertyChangedCondition. */
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400161template <typename T>
162auto propertyChangedTo(
Brad Bishop7b337772017-01-12 16:11:24 -0500163 const char* iface,
164 const char* property,
Brad Bishopfb083c22017-01-19 09:22:04 -0500165 T&& val)
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400166{
Brad Bishopfb083c22017-01-19 09:22:04 -0500167 auto condition = [val = std::move(val)](T && arg)
Brad Bishopd1bbf3a2016-12-01 00:03:26 -0500168 {
169 return arg == val;
170 };
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400171 using U = decltype(condition);
Brad Bishop143522e2017-01-19 09:12:54 -0500172 return details::property_condition::PropertyChangedCondition<T, U>(
Brad Bishop7b337772017-01-12 16:11:24 -0500173 iface, property, std::move(condition));
Brad Bishopbf5aa9c2016-10-19 21:19:04 -0400174}
175
Brad Bishop3d57f502016-10-19 12:18:41 -0400176} // namespace filters
177} // namespace manager
178} // namespace inventory
179} // namespace phosphor
180
181// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4