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