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