1 /**
2  * @file propertywatch.hpp
3  * @brief PropertyWatch class declarations.
4  *
5  * In general class users should include propertywatchimpl.hpp instead to avoid
6  * link failures.
7  */
8 #pragma once
9 
10 #include "data_types.hpp"
11 #include "watch.hpp"
12 
13 namespace phosphor
14 {
15 namespace dbus
16 {
17 namespace monitoring
18 {
19 
20 class Callback;
21 
22 /** @class PropertyWatch
23  *  @brief Type agnostic, factored out logic for property watches.
24  *
25  *  A property watch maintains the state of one or more DBus properties
26  *  as specified by the supplied index.
27  */
28 template <typename DBusInterfaceType>
29 class PropertyWatch : public Watch
30 {
31   public:
32     PropertyWatch() = delete;
33     PropertyWatch(const PropertyWatch&) = delete;
34     PropertyWatch(PropertyWatch&&) = default;
35     PropertyWatch& operator=(const PropertyWatch&) = delete;
36     PropertyWatch& operator=(PropertyWatch&&) = default;
37     virtual ~PropertyWatch() = default;
38     PropertyWatch(const PropertyIndex& watchIndex,
39                   Callback* callback = nullptr) :
40         Watch(),
41         index(watchIndex), cb(callback), alreadyRan(false)
42     {
43     }
44 
45     /** @brief Start the watch.
46      *
47      *  Watch start interface implementation for PropertyWatch.
48      */
49     void start() override;
50 
51     /** @brief Run the watch callback method.
52      *
53      *  Watch callback interface implementation for PropertyWatch.
54      */
55     void callback(Context ctx) override;
56 
57     /** @brief Update properties.
58      *
59      *  Subclasses to query the properties specified by the index
60      *  and update the cache.
61      *
62      *  @param[in] busName - The busname hosting the interface to query.
63      *  @param[in] path - The path of the interface to query.
64      *  @param[in] interface - The interface to query.
65      */
66     virtual void updateProperties(const std::string& busName,
67                                   const std::string& path,
68                                   const std::string& interface) = 0;
69 
70     /** @brief Dbus signal callback for PropertiesChanged.
71      *
72      *  Subclasses to update the cache.
73      *
74      *  @param[in] message - The org.freedesktop.DBus.PropertiesChanged
75      *               message.
76      *  @param[in] path - The path associated with the message.
77      *  @param[in] interface - The interface associated with the message.
78      */
79     virtual void propertiesChanged(sdbusplus::message::message&,
80                                    const std::string& path,
81                                    const std::string& interface) = 0;
82 
83     /** @brief Dbus signal callback for InterfacesAdded.
84      *
85      *  Subclasses to update the cache.
86      *
87      *  @param[in] msg - The org.freedesktop.DBus.PropertiesChanged
88      *               message.
89      */
90     virtual void interfacesAdded(sdbusplus::message::message& msg) = 0;
91 
92   protected:
93     /** @brief Property names and their associated storage. */
94     const PropertyIndex& index;
95 
96     /** @brief Optional callback method. */
97     Callback* const cb;
98 
99     /** @brief The start method should only be invoked once. */
100     bool alreadyRan;
101 };
102 
103 /** @class PropertyWatchOfType
104  *  @brief Type specific logic for PropertyWatch.
105  *
106  *  @tparam DBusInterfaceType - DBus access delegate.
107  *  @tparam T - The type of the properties being watched.
108  */
109 template <typename T, typename DBusInterfaceType>
110 class PropertyWatchOfType : public PropertyWatch<DBusInterfaceType>
111 {
112   public:
113     PropertyWatchOfType() = default;
114     PropertyWatchOfType(const PropertyWatchOfType&) = delete;
115     PropertyWatchOfType(PropertyWatchOfType&&) = default;
116     PropertyWatchOfType& operator=(const PropertyWatchOfType&) = delete;
117     PropertyWatchOfType& operator=(PropertyWatchOfType&&) = default;
118     ~PropertyWatchOfType() = default;
119     PropertyWatchOfType(const std::vector<std::function<bool(T)>>& filterOps,
120                         const PropertyIndex& watchIndex, Callback& callback) :
121         PropertyWatch<DBusInterfaceType>(watchIndex, &callback),
122         filterOps(filterOps)
123     {
124     }
125     PropertyWatchOfType(const std::vector<std::function<bool(T)>>& filterOps,
126                         const PropertyIndex& watchIndex) :
127         PropertyWatch<DBusInterfaceType>(watchIndex, nullptr),
128         filterOps(filterOps)
129     {
130     }
131 
132     /** @brief PropertyMatch implementation for PropertyWatchOfType.
133      *
134      *  @param[in] busName - The busname hosting the interface to query.
135      *  @param[in] path - The path of the interface to query.
136      *  @param[in] interface - The interface to query.
137      */
138     void updateProperties(const std::string& busName, const std::string& path,
139                           const std::string& interface) override;
140 
141     /** @brief PropertyMatch implementation for PropertyWatchOfType.
142      *
143      *  @param[in] msg - The org.freedesktop.DBus.PropertiesChanged
144      *               message.
145      *  @param[in] path - The path associated with the message.
146      *  @param[in] interface - The interface associated with the message.
147      */
148     void propertiesChanged(sdbusplus::message::message& msg,
149                            const std::string& path,
150                            const std::string& interface) override;
151 
152     /** @brief DBus agnostic implementation of interfacesAdded.
153      *
154      *  @param[in] path - The path of the properties that changed.
155      *  @param[in] interface - The interface of the properties that
156      *                  changed.
157      *  @param[in] properites - The properties that changed.
158      */
159     void propertiesChanged(const std::string& path,
160                            const std::string& interface,
161                            const PropertiesChanged<T>& properties);
162 
163     /** @brief PropertyMatch implementation for PropertyWatchOfType.
164      *
165      *  @param[in] msg - The org.freedesktop.DBus.PropertiesChanged
166      *               message.
167      */
168     void interfacesAdded(sdbusplus::message::message& msg) override;
169 
170     /** @brief DBus agnostic implementation of interfacesAdded.
171      *
172      *  @param[in] path - The path of the added interfaces.
173      *  @param[in] interfaces - The added interfaces.
174      */
175     void interfacesAdded(const std::string& path,
176                          const InterfacesAdded<T>& interfaces);
177 
178   private:
179     /** @brief List of filter operations to perform on property changes. */
180     const std::vector<std::function<bool(T)>> filterOps;
181 };
182 
183 } // namespace monitoring
184 } // namespace dbus
185 } // namespace phosphor
186