xref: /openbmc/phosphor-fan-presence/control/functor.hpp (revision 926df663de38c4ab643a7d7f1556b2a8dd3e5d9f)
138a93a8aSMatthew Barth #pragma once
238a93a8aSMatthew Barth 
338a93a8aSMatthew Barth #include "types.hpp"
4336f18a5SMatthew Barth #include "sdbusplus.hpp"
538a93a8aSMatthew Barth #include <phosphor-logging/log.hpp>
638a93a8aSMatthew Barth 
738a93a8aSMatthew Barth namespace phosphor
838a93a8aSMatthew Barth {
938a93a8aSMatthew Barth namespace fan
1038a93a8aSMatthew Barth {
1138a93a8aSMatthew Barth namespace control
1238a93a8aSMatthew Barth {
1338a93a8aSMatthew Barth class Zone;
1438a93a8aSMatthew Barth 
15336f18a5SMatthew Barth using namespace phosphor::fan;
165a302576SMatthew Barth using namespace sdbusplus::bus::match;
1738a93a8aSMatthew Barth using namespace phosphor::logging;
1838a93a8aSMatthew Barth 
1938a93a8aSMatthew Barth /**
201b3e9602SMatthew Barth  * @brief Create a zone handler function object
211b3e9602SMatthew Barth  *
221b3e9602SMatthew Barth  * @param[in] handler - The handler being created
231b3e9602SMatthew Barth  *
241b3e9602SMatthew Barth  * @return - The created zone handler function object
251b3e9602SMatthew Barth  */
261b3e9602SMatthew Barth template <typename T>
271b3e9602SMatthew Barth auto make_zoneHandler(T&& handler)
281b3e9602SMatthew Barth {
291b3e9602SMatthew Barth     return ZoneHandler(std::forward<T>(handler));
301b3e9602SMatthew Barth }
311b3e9602SMatthew Barth 
321b3e9602SMatthew Barth /**
331b4de26aSMatthew Barth  * @brief Create a trigger function object
341b4de26aSMatthew Barth  *
351b4de26aSMatthew Barth  * @param[in] trigger - The trigger being created
361b4de26aSMatthew Barth  *
371b4de26aSMatthew Barth  * @return - The created trigger function object
381b4de26aSMatthew Barth  */
391b4de26aSMatthew Barth template <typename T>
401b4de26aSMatthew Barth auto make_trigger(T&& trigger)
411b4de26aSMatthew Barth {
421b4de26aSMatthew Barth    return Trigger(std::forward<T>(trigger));
431b4de26aSMatthew Barth }
441b4de26aSMatthew Barth 
451b4de26aSMatthew Barth /**
4638a93a8aSMatthew Barth  * @brief Create a handler function object
4738a93a8aSMatthew Barth  *
4838a93a8aSMatthew Barth  * @param[in] handler - The handler being created
4938a93a8aSMatthew Barth  *
5038a93a8aSMatthew Barth  * @return - The created handler function object
5138a93a8aSMatthew Barth  */
52*926df663SMatthew Barth template <typename T, typename U>
53*926df663SMatthew Barth auto make_handler(U&& handler)
5438a93a8aSMatthew Barth {
55*926df663SMatthew Barth     return T(std::forward<U>(handler));
5638a93a8aSMatthew Barth }
5738a93a8aSMatthew Barth 
5838a93a8aSMatthew Barth /**
5917d1fe23SMatthew Barth  * @brief Create an action function object
6017d1fe23SMatthew Barth  *
6117d1fe23SMatthew Barth  * @param[in] action - The action being created
6217d1fe23SMatthew Barth  *
6317d1fe23SMatthew Barth  * @return - The created action function object
6417d1fe23SMatthew Barth  */
6517d1fe23SMatthew Barth template <typename T>
6617d1fe23SMatthew Barth auto make_action(T&& action)
6717d1fe23SMatthew Barth {
6817d1fe23SMatthew Barth     return Action(std::forward<T>(action));
6917d1fe23SMatthew Barth }
7017d1fe23SMatthew Barth 
7117d1fe23SMatthew Barth /**
72*926df663SMatthew Barth  * @struct Properties
73*926df663SMatthew Barth  * @brief A set of match filter functors for Dbus property values. Each
74*926df663SMatthew Barth  * functor provides an associated process for retrieving the value
75*926df663SMatthew Barth  * for a given property and providing it to the given handler function.
7638a93a8aSMatthew Barth  *
7738a93a8aSMatthew Barth  * @tparam T - The type of the property value
7838a93a8aSMatthew Barth  * @tparam U - The type of the handler
7938a93a8aSMatthew Barth  */
8038a93a8aSMatthew Barth template <typename T, typename U>
81*926df663SMatthew Barth struct Properties
8238a93a8aSMatthew Barth {
83*926df663SMatthew Barth     Properties() = delete;
84*926df663SMatthew Barth     ~Properties() = default;
85*926df663SMatthew Barth     Properties(const Properties&) = default;
86*926df663SMatthew Barth     Properties& operator=(const Properties&) = default;
87*926df663SMatthew Barth     Properties(Properties&&) = default;
88*926df663SMatthew Barth     Properties& operator=(Properties&&) = default;
89*926df663SMatthew Barth     explicit Properties(U&& handler) :
90*926df663SMatthew Barth         _path(""),
91*926df663SMatthew Barth         _iface(""),
92*926df663SMatthew Barth         _property(""),
93*926df663SMatthew Barth         _handler(std::forward<U>(handler)) { }
94*926df663SMatthew Barth     Properties(const char* path,
95336f18a5SMatthew Barth                const char* iface,
9638a93a8aSMatthew Barth                const char* property,
9738a93a8aSMatthew Barth                U&& handler) :
98336f18a5SMatthew Barth         _path(path),
9938a93a8aSMatthew Barth         _iface(iface),
10038a93a8aSMatthew Barth         _property(property),
10138a93a8aSMatthew Barth         _handler(std::forward<U>(handler)) { }
10238a93a8aSMatthew Barth 
10338a93a8aSMatthew Barth     /** @brief Run signal handler function
10438a93a8aSMatthew Barth      *
10538a93a8aSMatthew Barth      * Extract the property from the PropertiesChanged
106*926df663SMatthew Barth      * message and run the handler function.
10738a93a8aSMatthew Barth      */
108336f18a5SMatthew Barth     void operator()(sdbusplus::bus::bus& bus,
10938a93a8aSMatthew Barth                     sdbusplus::message::message& msg,
11038a93a8aSMatthew Barth                     Zone& zone) const
11138a93a8aSMatthew Barth     {
112336f18a5SMatthew Barth         if (msg)
113336f18a5SMatthew Barth         {
11438a93a8aSMatthew Barth             std::map<std::string, sdbusplus::message::variant<T>> properties;
115d5cfdbe0SMatthew Barth             std::string iface;
11638a93a8aSMatthew Barth 
11738a93a8aSMatthew Barth             msg.read(iface);
118d5cfdbe0SMatthew Barth             if (iface != _iface)
11938a93a8aSMatthew Barth             {
12038a93a8aSMatthew Barth                 return;
12138a93a8aSMatthew Barth             }
12238a93a8aSMatthew Barth 
12338a93a8aSMatthew Barth             msg.read(properties);
12438a93a8aSMatthew Barth             auto it = properties.find(_property);
12538a93a8aSMatthew Barth             if (it == properties.cend())
12638a93a8aSMatthew Barth             {
12738a93a8aSMatthew Barth                 log<level::ERR>("Unable to find property on interface",
12838a93a8aSMatthew Barth                                 entry("PROPERTY=%s", _property),
129e65f617cSMatthew Barth                                 entry("INTERFACE=%s", _iface),
130e65f617cSMatthew Barth                                 entry("PATH=%s", _path));
13138a93a8aSMatthew Barth                 return;
13238a93a8aSMatthew Barth             }
13338a93a8aSMatthew Barth 
1344978e06cSWilliam A. Kennington III             _handler(zone, std::forward<T>(
1354978e06cSWilliam A. Kennington III                          sdbusplus::message::variant_ns::get<T>(it->second)));
13638a93a8aSMatthew Barth         }
137336f18a5SMatthew Barth         else
138336f18a5SMatthew Barth         {
139336f18a5SMatthew Barth             try
140336f18a5SMatthew Barth             {
141766f8545SMatthew Barth                 auto val = zone.getPropertyByName<T>(_path, _iface, _property);
142336f18a5SMatthew Barth                 _handler(zone, std::forward<T>(val));
143336f18a5SMatthew Barth             }
14486be476bSMatthew Barth             catch (const sdbusplus::exception::SdBusError&)
14586be476bSMatthew Barth             {
14686be476bSMatthew Barth                 // Property will not be used unless a property changed
14786be476bSMatthew Barth                 // signal message is received for this property.
14886be476bSMatthew Barth             }
14986be476bSMatthew Barth             catch (const util::DBusError&)
150336f18a5SMatthew Barth             {
151336f18a5SMatthew Barth                 // Property will not be used unless a property changed
152336f18a5SMatthew Barth                 // signal message is received for this property.
153336f18a5SMatthew Barth             }
154336f18a5SMatthew Barth         }
155336f18a5SMatthew Barth     }
15638a93a8aSMatthew Barth 
157*926df663SMatthew Barth     /** @brief Run init handler function
158*926df663SMatthew Barth      *
159*926df663SMatthew Barth      * Get the property from each member object of the group
160*926df663SMatthew Barth      * and run the handler function.
161*926df663SMatthew Barth      */
162*926df663SMatthew Barth     void operator()(Zone& zone, const Group& group) const
163*926df663SMatthew Barth     {
164*926df663SMatthew Barth         std::for_each(
165*926df663SMatthew Barth             group.begin(),
166*926df663SMatthew Barth             group.end(),
167*926df663SMatthew Barth             [&zone, &group, handler = std::move(_handler)](auto const& member)
168*926df663SMatthew Barth             {
169*926df663SMatthew Barth                 auto path = std::get<pathPos>(member);
170*926df663SMatthew Barth                 auto intf = std::get<intfPos>(member);
171*926df663SMatthew Barth                 auto prop = std::get<propPos>(member);
172*926df663SMatthew Barth                 try
173*926df663SMatthew Barth                 {
174*926df663SMatthew Barth                     auto val = zone.getPropertyByName<T>(path, intf, prop);
175*926df663SMatthew Barth                     handler(zone, std::forward<T>(val));
176*926df663SMatthew Barth                 }
177*926df663SMatthew Barth                 catch (const sdbusplus::exception::SdBusError&)
178*926df663SMatthew Barth                 {
179*926df663SMatthew Barth                     // Property value not sent to handler
180*926df663SMatthew Barth                 }
181*926df663SMatthew Barth                 catch (const util::DBusError&)
182*926df663SMatthew Barth                 {
183*926df663SMatthew Barth                     // Property value not sent to handler
184*926df663SMatthew Barth                 }
185*926df663SMatthew Barth             }
186*926df663SMatthew Barth         );
187*926df663SMatthew Barth     }
188*926df663SMatthew Barth 
18938a93a8aSMatthew Barth private:
190336f18a5SMatthew Barth     const char* _path;
19138a93a8aSMatthew Barth     const char* _iface;
19238a93a8aSMatthew Barth     const char* _property;
19338a93a8aSMatthew Barth     U _handler;
19438a93a8aSMatthew Barth };
19538a93a8aSMatthew Barth 
19638a93a8aSMatthew Barth /**
19738a93a8aSMatthew Barth  * @brief Used to process a Dbus property changed signal event
19838a93a8aSMatthew Barth  *
199336f18a5SMatthew Barth  * @param[in] path - Object path
200336f18a5SMatthew Barth  * @param[in] iface - Object interface
201336f18a5SMatthew Barth  * @param[in] property - Object property
20238a93a8aSMatthew Barth  * @param[in] handler - Handler function to perform
20338a93a8aSMatthew Barth  *
20438a93a8aSMatthew Barth  * @tparam T - The type of the property
20538a93a8aSMatthew Barth  * @tparam U - The type of the handler
20638a93a8aSMatthew Barth  */
20738a93a8aSMatthew Barth template <typename T, typename U>
208*926df663SMatthew Barth auto propertiesChanged(const char* path,
209336f18a5SMatthew Barth                        const char* iface,
21038a93a8aSMatthew Barth                        const char* property,
21138a93a8aSMatthew Barth                        U&& handler)
21238a93a8aSMatthew Barth {
213*926df663SMatthew Barth     return Properties<T, U>(path,
214336f18a5SMatthew Barth                             iface,
215336f18a5SMatthew Barth                             property,
216336f18a5SMatthew Barth                             std::forward<U>(handler));
21738a93a8aSMatthew Barth }
21838a93a8aSMatthew Barth 
219eb639c57SMatthew Barth /**
220*926df663SMatthew Barth  * @brief Used to get the property value of an object
221*926df663SMatthew Barth  *
222*926df663SMatthew Barth  * @param[in] handler - Handler function to perform
223*926df663SMatthew Barth  *
224*926df663SMatthew Barth  * @tparam T - The type of the property
225*926df663SMatthew Barth  * @tparam U - The type of the handler
226*926df663SMatthew Barth  */
227*926df663SMatthew Barth template <typename T, typename U>
228*926df663SMatthew Barth auto getProperty(U&& handler)
229*926df663SMatthew Barth {
230*926df663SMatthew Barth     return Properties<T, U>(std::forward<U>(handler));
231*926df663SMatthew Barth }
232*926df663SMatthew Barth 
233*926df663SMatthew Barth /**
234eb639c57SMatthew Barth  * @struct Interface Added
235eb639c57SMatthew Barth  * @brief A match filter functor for Dbus interface added signals
236eb639c57SMatthew Barth  *
237eb639c57SMatthew Barth  * @tparam T - The type of the property value
238eb639c57SMatthew Barth  * @tparam U - The type of the handler
239eb639c57SMatthew Barth  */
240eb639c57SMatthew Barth template <typename T, typename U>
241eb639c57SMatthew Barth struct InterfaceAdded
242eb639c57SMatthew Barth {
243eb639c57SMatthew Barth     InterfaceAdded() = delete;
244eb639c57SMatthew Barth     ~InterfaceAdded() = default;
245eb639c57SMatthew Barth     InterfaceAdded(const InterfaceAdded&) = default;
246eb639c57SMatthew Barth     InterfaceAdded& operator=(const InterfaceAdded&) = default;
247eb639c57SMatthew Barth     InterfaceAdded(InterfaceAdded&&) = default;
248eb639c57SMatthew Barth     InterfaceAdded& operator=(InterfaceAdded&&) = default;
249eb639c57SMatthew Barth     InterfaceAdded(const char* path,
250eb639c57SMatthew Barth                    const char* iface,
251eb639c57SMatthew Barth                    const char* property,
252eb639c57SMatthew Barth                    U&& handler) :
253eb639c57SMatthew Barth         _path(path),
254eb639c57SMatthew Barth         _iface(iface),
255eb639c57SMatthew Barth         _property(property),
256eb639c57SMatthew Barth         _handler(std::forward<U>(handler)) { }
257eb639c57SMatthew Barth 
258eb639c57SMatthew Barth     /** @brief Run signal handler function
259eb639c57SMatthew Barth      *
260eb639c57SMatthew Barth      * Extract the property from the InterfacesAdded
261eb639c57SMatthew Barth      * message and run the handler function.
262eb639c57SMatthew Barth      */
263eb639c57SMatthew Barth     void operator()(sdbusplus::bus::bus&,
264eb639c57SMatthew Barth                     sdbusplus::message::message& msg,
265eb639c57SMatthew Barth                     Zone& zone) const
266eb639c57SMatthew Barth     {
267336f18a5SMatthew Barth         if (msg)
268336f18a5SMatthew Barth         {
269eb639c57SMatthew Barth             std::map<std::string,
270eb639c57SMatthew Barth                      std::map<std::string,
271eb639c57SMatthew Barth                               sdbusplus::message::variant<T>>> intfProp;
272eb639c57SMatthew Barth             sdbusplus::message::object_path op;
273eb639c57SMatthew Barth 
274eb639c57SMatthew Barth             msg.read(op);
275d5cfdbe0SMatthew Barth             if (static_cast<const std::string&>(op) != _path)
276eb639c57SMatthew Barth             {
277eb639c57SMatthew Barth                 // Object path does not match this handler's path
278eb639c57SMatthew Barth                 return;
279eb639c57SMatthew Barth             }
280eb639c57SMatthew Barth 
281eb639c57SMatthew Barth             msg.read(intfProp);
282eb639c57SMatthew Barth             auto itIntf = intfProp.find(_iface);
283eb639c57SMatthew Barth             if (itIntf == intfProp.cend())
284eb639c57SMatthew Barth             {
285eb639c57SMatthew Barth                 // Interface not found on this handler's path
286eb639c57SMatthew Barth                 return;
287eb639c57SMatthew Barth             }
288eb639c57SMatthew Barth             auto itProp = itIntf->second.find(_property);
289eb639c57SMatthew Barth             if (itProp == itIntf->second.cend())
290eb639c57SMatthew Barth             {
291eb639c57SMatthew Barth                 // Property not found on this handler's path
292eb639c57SMatthew Barth                 return;
293eb639c57SMatthew Barth             }
294eb639c57SMatthew Barth 
2954978e06cSWilliam A. Kennington III             _handler(zone, std::forward<T>(
2964978e06cSWilliam A. Kennington III                          sdbusplus::message::variant_ns::get<T>(itProp->second)));
297eb639c57SMatthew Barth         }
298336f18a5SMatthew Barth     }
299eb639c57SMatthew Barth 
300eb639c57SMatthew Barth private:
301eb639c57SMatthew Barth     const char* _path;
302eb639c57SMatthew Barth     const char* _iface;
303eb639c57SMatthew Barth     const char* _property;
304eb639c57SMatthew Barth     U _handler;
305eb639c57SMatthew Barth };
306eb639c57SMatthew Barth 
307eb639c57SMatthew Barth /**
308*926df663SMatthew Barth  * @brief Used to process a Dbus interfaces added signal event
309eb639c57SMatthew Barth  *
310eb639c57SMatthew Barth  * @param[in] path - Object path
311eb639c57SMatthew Barth  * @param[in] iface - Object interface
312eb639c57SMatthew Barth  * @param[in] property - Object property
313eb639c57SMatthew Barth  * @param[in] handler - Handler function to perform
314eb639c57SMatthew Barth  *
315eb639c57SMatthew Barth  * @tparam T - The type of the property
316eb639c57SMatthew Barth  * @tparam U - The type of the handler
317eb639c57SMatthew Barth  */
318eb639c57SMatthew Barth template <typename T, typename U>
319*926df663SMatthew Barth auto interfacesAdded(const char* path,
320eb639c57SMatthew Barth                      const char* iface,
321eb639c57SMatthew Barth                      const char* property,
322eb639c57SMatthew Barth                      U&& handler)
323eb639c57SMatthew Barth {
324eb639c57SMatthew Barth     return InterfaceAdded<T, U>(path,
325eb639c57SMatthew Barth                                 iface,
326eb639c57SMatthew Barth                                 property,
327eb639c57SMatthew Barth                                 std::forward<U>(handler));
328eb639c57SMatthew Barth }
329eb639c57SMatthew Barth 
3308fa02dabSMatthew Barth /**
3311499a5c3SMatthew Barth  * @struct Interface Removed
3321499a5c3SMatthew Barth  * @brief A match filter functor for Dbus interface removed signals
3331499a5c3SMatthew Barth  *
3341499a5c3SMatthew Barth  * @tparam U - The type of the handler
3351499a5c3SMatthew Barth  */
3361499a5c3SMatthew Barth template <typename U>
3371499a5c3SMatthew Barth struct InterfaceRemoved
3381499a5c3SMatthew Barth {
3391499a5c3SMatthew Barth     InterfaceRemoved() = delete;
3401499a5c3SMatthew Barth     ~InterfaceRemoved() = default;
3411499a5c3SMatthew Barth     InterfaceRemoved(const InterfaceRemoved&) = default;
3421499a5c3SMatthew Barth     InterfaceRemoved& operator=(const InterfaceRemoved&) = default;
3431499a5c3SMatthew Barth     InterfaceRemoved(InterfaceRemoved&&) = default;
3441499a5c3SMatthew Barth     InterfaceRemoved& operator=(InterfaceRemoved&&) = default;
3451499a5c3SMatthew Barth     InterfaceRemoved(const char* path,
3461499a5c3SMatthew Barth                      const char* iface,
3471499a5c3SMatthew Barth                      U&& handler) :
3481499a5c3SMatthew Barth         _path(path),
3491499a5c3SMatthew Barth         _iface(iface),
3501499a5c3SMatthew Barth         _handler(std::forward<U>(handler)) { }
3511499a5c3SMatthew Barth 
3521499a5c3SMatthew Barth     /** @brief Run signal handler function
3531499a5c3SMatthew Barth      *
3541499a5c3SMatthew Barth      * Extract the property from the InterfacesRemoved
3551499a5c3SMatthew Barth      * message and run the handler function.
3561499a5c3SMatthew Barth      */
3571499a5c3SMatthew Barth     void operator()(sdbusplus::bus::bus&,
3581499a5c3SMatthew Barth                     sdbusplus::message::message& msg,
3591499a5c3SMatthew Barth                     Zone& zone) const
3601499a5c3SMatthew Barth     {
3611499a5c3SMatthew Barth         if (msg)
3621499a5c3SMatthew Barth         {
3631499a5c3SMatthew Barth             std::vector<std::string> intfs;
3641499a5c3SMatthew Barth             sdbusplus::message::object_path op;
3651499a5c3SMatthew Barth 
3661499a5c3SMatthew Barth             msg.read(op);
3671499a5c3SMatthew Barth             if (static_cast<const std::string&>(op) != _path)
3681499a5c3SMatthew Barth             {
3691499a5c3SMatthew Barth                 // Object path does not match this handler's path
3701499a5c3SMatthew Barth                 return;
3711499a5c3SMatthew Barth             }
3721499a5c3SMatthew Barth 
3731499a5c3SMatthew Barth             msg.read(intfs);
3741499a5c3SMatthew Barth             auto itIntf = std::find(intfs.begin(), intfs.end(), _iface);
3751499a5c3SMatthew Barth             if (itIntf == intfs.cend())
3761499a5c3SMatthew Barth             {
3771499a5c3SMatthew Barth                 // Interface not found on this handler's path
3781499a5c3SMatthew Barth                 return;
3791499a5c3SMatthew Barth             }
3801499a5c3SMatthew Barth 
3811499a5c3SMatthew Barth             _handler(zone);
3821499a5c3SMatthew Barth         }
3831499a5c3SMatthew Barth     }
3841499a5c3SMatthew Barth 
3851499a5c3SMatthew Barth private:
3861499a5c3SMatthew Barth     const char* _path;
3871499a5c3SMatthew Barth     const char* _iface;
3881499a5c3SMatthew Barth     U _handler;
3891499a5c3SMatthew Barth };
3901499a5c3SMatthew Barth 
3911499a5c3SMatthew Barth /**
392*926df663SMatthew Barth  * @brief Used to process a Dbus interfaces removed signal event
3931499a5c3SMatthew Barth  *
3941499a5c3SMatthew Barth  * @param[in] path - Object path
3951499a5c3SMatthew Barth  * @param[in] iface - Object interface
3961499a5c3SMatthew Barth  * @param[in] handler - Handler function to perform
3971499a5c3SMatthew Barth  *
3981499a5c3SMatthew Barth  * @tparam U - The type of the handler
3991499a5c3SMatthew Barth  */
4001499a5c3SMatthew Barth template <typename U>
401*926df663SMatthew Barth auto interfacesRemoved(const char* path,
4021499a5c3SMatthew Barth                        const char* iface,
4031499a5c3SMatthew Barth                        U&& handler)
4041499a5c3SMatthew Barth {
4051499a5c3SMatthew Barth     return InterfaceRemoved<U>(path,
4061499a5c3SMatthew Barth                                iface,
4071499a5c3SMatthew Barth                                std::forward<U>(handler));
4081499a5c3SMatthew Barth }
4091499a5c3SMatthew Barth 
4101499a5c3SMatthew Barth /**
411*926df663SMatthew Barth  * @struct Name Owner
412*926df663SMatthew Barth  * @brief A functor for Dbus name owner signals and methods
4138fa02dabSMatthew Barth  *
4148fa02dabSMatthew Barth  * @tparam U - The type of the handler
4158fa02dabSMatthew Barth  */
4168fa02dabSMatthew Barth template <typename U>
417*926df663SMatthew Barth struct NameOwner
4188fa02dabSMatthew Barth {
419*926df663SMatthew Barth     NameOwner() = delete;
420*926df663SMatthew Barth     ~NameOwner() = default;
421*926df663SMatthew Barth     NameOwner(const NameOwner&) = default;
422*926df663SMatthew Barth     NameOwner& operator=(const NameOwner&) = default;
423*926df663SMatthew Barth     NameOwner(NameOwner&&) = default;
424*926df663SMatthew Barth     NameOwner& operator=(NameOwner&&) = default;
425*926df663SMatthew Barth     explicit NameOwner(U&& handler) :
4268fa02dabSMatthew Barth         _handler(std::forward<U>(handler)) { }
4278fa02dabSMatthew Barth 
4288fa02dabSMatthew Barth     /** @brief Run signal handler function
4298fa02dabSMatthew Barth      *
4308fa02dabSMatthew Barth      * Extract the name owner from the NameOwnerChanged
431*926df663SMatthew Barth      * message and run the handler function.
4328fa02dabSMatthew Barth      */
4338fa02dabSMatthew Barth     void operator()(sdbusplus::bus::bus& bus,
4348fa02dabSMatthew Barth                     sdbusplus::message::message& msg,
4358fa02dabSMatthew Barth                     Zone& zone) const
4368fa02dabSMatthew Barth     {
4375a302576SMatthew Barth         std::string name;
4385a302576SMatthew Barth         bool hasOwner = false;
4398fa02dabSMatthew Barth         if (msg)
4408fa02dabSMatthew Barth         {
4415a302576SMatthew Barth             // Handle NameOwnerChanged signals
4425a302576SMatthew Barth             msg.read(name);
4435a302576SMatthew Barth 
4445a302576SMatthew Barth             std::string oldOwn;
4455a302576SMatthew Barth             msg.read(oldOwn);
4465a302576SMatthew Barth 
4475a302576SMatthew Barth             std::string newOwn;
4485a302576SMatthew Barth             msg.read(newOwn);
4495a302576SMatthew Barth             if (!newOwn.empty())
4505a302576SMatthew Barth             {
4515a302576SMatthew Barth                 hasOwner = true;
4525a302576SMatthew Barth             }
453*926df663SMatthew Barth             _handler(zone, name, hasOwner);
4548fa02dabSMatthew Barth         }
455*926df663SMatthew Barth     }
456*926df663SMatthew Barth 
457*926df663SMatthew Barth     void operator()(Zone& zone,
458*926df663SMatthew Barth                     const Group& group) const
4598fa02dabSMatthew Barth     {
460*926df663SMatthew Barth         std::string name = "";
461*926df663SMatthew Barth         bool hasOwner = false;
462*926df663SMatthew Barth         std::for_each(
463*926df663SMatthew Barth             group.begin(),
464*926df663SMatthew Barth             group.end(),
465*926df663SMatthew Barth             [&zone, &group, &name, &hasOwner, handler = std::move(_handler)](
466*926df663SMatthew Barth                 auto const& member)
467*926df663SMatthew Barth             {
468*926df663SMatthew Barth                 auto path = std::get<pathPos>(member);
469*926df663SMatthew Barth                 auto intf = std::get<intfPos>(member);
4705a302576SMatthew Barth                 try
4715a302576SMatthew Barth                 {
472*926df663SMatthew Barth                     auto servName = zone.getService(path, intf);
473*926df663SMatthew Barth                     if (name != servName)
474*926df663SMatthew Barth                     {
475*926df663SMatthew Barth                         name = servName;
4765a302576SMatthew Barth                         hasOwner = util::SDBusPlus::callMethodAndRead<bool>(
477*926df663SMatthew Barth                                 zone.getBus(),
4785a302576SMatthew Barth                                 "org.freedesktop.DBus",
4795a302576SMatthew Barth                                 "/org/freedesktop/DBus",
4805a302576SMatthew Barth                                 "org.freedesktop.DBus",
4815a302576SMatthew Barth                                 "NameHasOwner",
4825a302576SMatthew Barth                                 name);
483*926df663SMatthew Barth                         // Update service name owner state list of a group
484*926df663SMatthew Barth                         handler(zone, name, hasOwner);
485*926df663SMatthew Barth                     }
4868fa02dabSMatthew Barth                 }
487ba7b5feaSMatt Spinler                 catch (const util::DBusMethodError& e)
4885a302576SMatthew Barth                 {
4895a302576SMatthew Barth                     // Failed to get service name owner state
490*926df663SMatthew Barth                     name = "";
4915a302576SMatthew Barth                     hasOwner = false;
4925a302576SMatthew Barth                 }
4935a302576SMatthew Barth 
494*926df663SMatthew Barth             }
495*926df663SMatthew Barth         );
4968fa02dabSMatthew Barth     }
4978fa02dabSMatthew Barth 
4988fa02dabSMatthew Barth private:
4998fa02dabSMatthew Barth     U _handler;
5008fa02dabSMatthew Barth };
5018fa02dabSMatthew Barth 
5028fa02dabSMatthew Barth /**
5038fa02dabSMatthew Barth  * @brief Used to process a Dbus name owner changed signal event
5048fa02dabSMatthew Barth  *
5058fa02dabSMatthew Barth  * @param[in] handler - Handler function to perform
5068fa02dabSMatthew Barth  *
5078fa02dabSMatthew Barth  * @tparam U - The type of the handler
5088fa02dabSMatthew Barth  *
5098fa02dabSMatthew Barth  * @return - The NameOwnerChanged signal struct
5108fa02dabSMatthew Barth  */
5118fa02dabSMatthew Barth template <typename U>
512*926df663SMatthew Barth auto nameOwnerChanged(U&& handler)
5138fa02dabSMatthew Barth {
514*926df663SMatthew Barth     return NameOwner<U>(std::forward<U>(handler));
515*926df663SMatthew Barth }
516*926df663SMatthew Barth 
517*926df663SMatthew Barth /**
518*926df663SMatthew Barth  * @brief Used to process the init of a name owner event
519*926df663SMatthew Barth  *
520*926df663SMatthew Barth  * @param[in] handler - Handler function to perform
521*926df663SMatthew Barth  *
522*926df663SMatthew Barth  * @tparam U - The type of the handler
523*926df663SMatthew Barth  *
524*926df663SMatthew Barth  * @return - The NameOwnerChanged signal struct
525*926df663SMatthew Barth  */
526*926df663SMatthew Barth template <typename U>
527*926df663SMatthew Barth auto nameHasOwner(U&& handler)
528*926df663SMatthew Barth {
529*926df663SMatthew Barth     return NameOwner<U>(std::forward<U>(handler));
5308fa02dabSMatthew Barth }
5318fa02dabSMatthew Barth 
53238a93a8aSMatthew Barth } // namespace control
53338a93a8aSMatthew Barth } // namespace fan
53438a93a8aSMatthew Barth } // namespace phosphor
535