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