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