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