xref: /openbmc/phosphor-fan-presence/control/functor.hpp (revision 3e1bb274a9871c2f78488a84c748654394d28fbd)
138a93a8aSMatthew Barth #pragma once
238a93a8aSMatthew Barth 
3336f18a5SMatthew Barth #include "sdbusplus.hpp"
4*3e1bb274SMatthew Barth #include "types.hpp"
5*3e1bb274SMatthew Barth 
638a93a8aSMatthew Barth #include <phosphor-logging/log.hpp>
738a93a8aSMatthew Barth 
838a93a8aSMatthew Barth namespace phosphor
938a93a8aSMatthew Barth {
1038a93a8aSMatthew Barth namespace fan
1138a93a8aSMatthew Barth {
1238a93a8aSMatthew Barth namespace control
1338a93a8aSMatthew Barth {
1438a93a8aSMatthew Barth class Zone;
1538a93a8aSMatthew Barth 
16336f18a5SMatthew Barth using namespace phosphor::fan;
175a302576SMatthew Barth using namespace sdbusplus::bus::match;
1838a93a8aSMatthew Barth using namespace phosphor::logging;
1938a93a8aSMatthew Barth 
2038a93a8aSMatthew Barth /**
211b3e9602SMatthew Barth  * @brief Create a zone handler function object
221b3e9602SMatthew Barth  *
231b3e9602SMatthew Barth  * @param[in] handler - The handler being created
241b3e9602SMatthew Barth  *
251b3e9602SMatthew Barth  * @return - The created zone handler function object
261b3e9602SMatthew Barth  */
271b3e9602SMatthew Barth template <typename T>
281b3e9602SMatthew Barth auto make_zoneHandler(T&& handler)
291b3e9602SMatthew Barth {
301b3e9602SMatthew Barth     return ZoneHandler(std::forward<T>(handler));
311b3e9602SMatthew Barth }
321b3e9602SMatthew Barth 
331b3e9602SMatthew Barth /**
341b4de26aSMatthew Barth  * @brief Create a trigger function object
351b4de26aSMatthew Barth  *
361b4de26aSMatthew Barth  * @param[in] trigger - The trigger being created
371b4de26aSMatthew Barth  *
381b4de26aSMatthew Barth  * @return - The created trigger function object
391b4de26aSMatthew Barth  */
401b4de26aSMatthew Barth template <typename T>
411b4de26aSMatthew Barth auto make_trigger(T&& trigger)
421b4de26aSMatthew Barth {
431b4de26aSMatthew Barth     return Trigger(std::forward<T>(trigger));
441b4de26aSMatthew Barth }
451b4de26aSMatthew Barth 
461b4de26aSMatthew Barth /**
4738a93a8aSMatthew Barth  * @brief Create a handler function object
4838a93a8aSMatthew Barth  *
4938a93a8aSMatthew Barth  * @param[in] handler - The handler being created
5038a93a8aSMatthew Barth  *
5138a93a8aSMatthew Barth  * @return - The created handler function object
5238a93a8aSMatthew Barth  */
53926df663SMatthew Barth template <typename T, typename U>
54926df663SMatthew Barth auto make_handler(U&& handler)
5538a93a8aSMatthew Barth {
56926df663SMatthew Barth     return T(std::forward<U>(handler));
5738a93a8aSMatthew Barth }
5838a93a8aSMatthew Barth 
5938a93a8aSMatthew Barth /**
6017d1fe23SMatthew Barth  * @brief Create an action function object
6117d1fe23SMatthew Barth  *
6217d1fe23SMatthew Barth  * @param[in] action - The action being created
6317d1fe23SMatthew Barth  *
6417d1fe23SMatthew Barth  * @return - The created action function object
6517d1fe23SMatthew Barth  */
6617d1fe23SMatthew Barth template <typename T>
6717d1fe23SMatthew Barth auto make_action(T&& action)
6817d1fe23SMatthew Barth {
6917d1fe23SMatthew Barth     return Action(std::forward<T>(action));
7017d1fe23SMatthew Barth }
7117d1fe23SMatthew Barth 
7217d1fe23SMatthew Barth /**
73926df663SMatthew Barth  * @struct Properties
74926df663SMatthew Barth  * @brief A set of match filter functors for Dbus property values. Each
75926df663SMatthew Barth  * functor provides an associated process for retrieving the value
76926df663SMatthew Barth  * for a given property and providing it to the given handler function.
7738a93a8aSMatthew Barth  *
7838a93a8aSMatthew Barth  * @tparam T - The type of the property value
7938a93a8aSMatthew Barth  * @tparam U - The type of the handler
8038a93a8aSMatthew Barth  */
8138a93a8aSMatthew Barth template <typename T, typename U>
82926df663SMatthew Barth struct Properties
8338a93a8aSMatthew Barth {
84926df663SMatthew Barth     Properties() = delete;
85926df663SMatthew Barth     ~Properties() = default;
86926df663SMatthew Barth     Properties(const Properties&) = default;
87926df663SMatthew Barth     Properties& operator=(const Properties&) = default;
88926df663SMatthew Barth     Properties(Properties&&) = default;
89926df663SMatthew Barth     Properties& operator=(Properties&&) = default;
90*3e1bb274SMatthew Barth     explicit Properties(U&& handler) : _handler(std::forward<U>(handler))
91*3e1bb274SMatthew Barth     {}
92*3e1bb274SMatthew Barth     Properties(const char* path, const char* intf, const char* prop,
9338a93a8aSMatthew Barth                U&& handler) :
94336f18a5SMatthew Barth         _path(path),
95*3e1bb274SMatthew Barth         _intf(intf), _prop(prop), _handler(std::forward<U>(handler))
96*3e1bb274SMatthew Barth     {}
9738a93a8aSMatthew Barth 
9838a93a8aSMatthew Barth     /** @brief Run signal handler function
9938a93a8aSMatthew Barth      *
10038a93a8aSMatthew Barth      * Extract the property from the PropertiesChanged
101926df663SMatthew Barth      * message and run the handler function.
10238a93a8aSMatthew Barth      */
103*3e1bb274SMatthew Barth     void operator()(sdbusplus::bus::bus& bus, sdbusplus::message::message& msg,
10438a93a8aSMatthew Barth                     Zone& zone) const
10538a93a8aSMatthew Barth     {
106336f18a5SMatthew Barth         if (msg)
107336f18a5SMatthew Barth         {
108469d1366SMatthew Barth             std::string intf;
109469d1366SMatthew Barth             msg.read(intf);
110469d1366SMatthew Barth             if (intf != _intf)
11138a93a8aSMatthew Barth             {
112469d1366SMatthew Barth                 // Interface name does not match on object
11338a93a8aSMatthew Barth                 return;
11438a93a8aSMatthew Barth             }
11538a93a8aSMatthew Barth 
1167f4c548dSMatthew Barth             std::map<std::string, PropertyVariantType> props;
117469d1366SMatthew Barth             msg.read(props);
118469d1366SMatthew Barth             auto it = props.find(_prop);
119469d1366SMatthew Barth             if (it == props.cend())
12038a93a8aSMatthew Barth             {
121469d1366SMatthew Barth                 // Property not included in dictionary of properties changed
12238a93a8aSMatthew Barth                 return;
12338a93a8aSMatthew Barth             }
12438a93a8aSMatthew Barth 
1257f4c548dSMatthew Barth             // Retrieve the property's value applying any visitors necessary
1267f4c548dSMatthew Barth             auto value =
1277f4c548dSMatthew Barth                 zone.getPropertyValueVisitor<T>(_intf, _prop, it->second);
1287f4c548dSMatthew Barth 
1297f4c548dSMatthew Barth             _handler(zone, _path, _intf, _prop, std::forward<T>(value));
13038a93a8aSMatthew Barth         }
131336f18a5SMatthew Barth         else
132336f18a5SMatthew Barth         {
133336f18a5SMatthew Barth             try
134336f18a5SMatthew Barth             {
135469d1366SMatthew Barth                 auto val = zone.getPropertyByName<T>(_path, _intf, _prop);
136469d1366SMatthew Barth                 _handler(zone, _path, _intf, _prop, std::forward<T>(val));
137336f18a5SMatthew Barth             }
13886be476bSMatthew Barth             catch (const sdbusplus::exception::SdBusError&)
13986be476bSMatthew Barth             {
14086be476bSMatthew Barth                 // Property will not be used unless a property changed
14186be476bSMatthew Barth                 // signal message is received for this property.
14286be476bSMatthew Barth             }
14386be476bSMatthew Barth             catch (const util::DBusError&)
144336f18a5SMatthew Barth             {
145336f18a5SMatthew Barth                 // Property will not be used unless a property changed
146336f18a5SMatthew Barth                 // signal message is received for this property.
147336f18a5SMatthew Barth             }
148336f18a5SMatthew Barth         }
149336f18a5SMatthew Barth     }
15038a93a8aSMatthew Barth 
151926df663SMatthew Barth     /** @brief Run init handler function
152926df663SMatthew Barth      *
153926df663SMatthew Barth      * Get the property from each member object of the group
154926df663SMatthew Barth      * and run the handler function.
155926df663SMatthew Barth      */
156926df663SMatthew Barth     void operator()(Zone& zone, const Group& group) const
157926df663SMatthew Barth     {
158926df663SMatthew Barth         std::for_each(
159*3e1bb274SMatthew Barth             group.begin(), group.end(),
160*3e1bb274SMatthew Barth             [&zone, handler = std::move(_handler)](auto const& member) {
161926df663SMatthew Barth                 auto path = std::get<pathPos>(member);
162926df663SMatthew Barth                 auto intf = std::get<intfPos>(member);
163926df663SMatthew Barth                 auto prop = std::get<propPos>(member);
164926df663SMatthew Barth                 try
165926df663SMatthew Barth                 {
166926df663SMatthew Barth                     auto val = zone.getPropertyByName<T>(path, intf, prop);
167469d1366SMatthew Barth                     handler(zone, path, intf, prop, std::forward<T>(val));
168926df663SMatthew Barth                 }
169926df663SMatthew Barth                 catch (const sdbusplus::exception::SdBusError&)
170926df663SMatthew Barth                 {
171926df663SMatthew Barth                     // Property value not sent to handler
172926df663SMatthew Barth                 }
173926df663SMatthew Barth                 catch (const util::DBusError&)
174926df663SMatthew Barth                 {
175926df663SMatthew Barth                     // Property value not sent to handler
176926df663SMatthew Barth                 }
177*3e1bb274SMatthew Barth             });
178926df663SMatthew Barth     }
179926df663SMatthew Barth 
18038a93a8aSMatthew Barth   private:
181336f18a5SMatthew Barth     const char* _path;
182469d1366SMatthew Barth     const char* _intf;
183469d1366SMatthew Barth     const char* _prop;
18438a93a8aSMatthew Barth     U _handler;
18538a93a8aSMatthew Barth };
18638a93a8aSMatthew Barth 
18738a93a8aSMatthew Barth /**
188469d1366SMatthew Barth  * @brief Used to process a Dbus properties changed signal event
18938a93a8aSMatthew Barth  *
190336f18a5SMatthew Barth  * @param[in] path - Object path
191469d1366SMatthew Barth  * @param[in] intf - Object interface
192469d1366SMatthew Barth  * @param[in] prop - Object property
19338a93a8aSMatthew Barth  * @param[in] handler - Handler function to perform
19438a93a8aSMatthew Barth  *
19538a93a8aSMatthew Barth  * @tparam T - The type of the property
19638a93a8aSMatthew Barth  * @tparam U - The type of the handler
19738a93a8aSMatthew Barth  */
19838a93a8aSMatthew Barth template <typename T, typename U>
199*3e1bb274SMatthew Barth auto propertiesChanged(const char* path, const char* intf, const char* prop,
20038a93a8aSMatthew Barth                        U&& handler)
20138a93a8aSMatthew Barth {
202*3e1bb274SMatthew Barth     return Properties<T, U>(path, intf, prop, std::forward<U>(handler));
20338a93a8aSMatthew Barth }
20438a93a8aSMatthew Barth 
205eb639c57SMatthew Barth /**
206469d1366SMatthew Barth  * @brief Used to get the properties of an event's group
207926df663SMatthew Barth  *
208926df663SMatthew Barth  * @param[in] handler - Handler function to perform
209926df663SMatthew Barth  *
210469d1366SMatthew Barth  * @tparam T - The type of all the properties
211926df663SMatthew Barth  * @tparam U - The type of the handler
212926df663SMatthew Barth  */
213926df663SMatthew Barth template <typename T, typename U>
214469d1366SMatthew Barth auto getProperties(U&& handler)
215926df663SMatthew Barth {
216926df663SMatthew Barth     return Properties<T, U>(std::forward<U>(handler));
217926df663SMatthew Barth }
218926df663SMatthew Barth 
219926df663SMatthew Barth /**
220469d1366SMatthew Barth  * @struct Interfaces Added
221469d1366SMatthew Barth  * @brief A match filter functor for Dbus interfaces added signals
222eb639c57SMatthew Barth  *
223eb639c57SMatthew Barth  * @tparam T - The type of the property value
224eb639c57SMatthew Barth  * @tparam U - The type of the handler
225eb639c57SMatthew Barth  */
226eb639c57SMatthew Barth template <typename T, typename U>
227469d1366SMatthew Barth struct InterfacesAdded
228eb639c57SMatthew Barth {
229469d1366SMatthew Barth     InterfacesAdded() = delete;
230469d1366SMatthew Barth     ~InterfacesAdded() = default;
231469d1366SMatthew Barth     InterfacesAdded(const InterfacesAdded&) = default;
232469d1366SMatthew Barth     InterfacesAdded& operator=(const InterfacesAdded&) = default;
233469d1366SMatthew Barth     InterfacesAdded(InterfacesAdded&&) = default;
234469d1366SMatthew Barth     InterfacesAdded& operator=(InterfacesAdded&&) = default;
235*3e1bb274SMatthew Barth     InterfacesAdded(const char* path, const char* intf, const char* prop,
236eb639c57SMatthew Barth                     U&& handler) :
237eb639c57SMatthew Barth         _path(path),
238*3e1bb274SMatthew Barth         _intf(intf), _prop(prop), _handler(std::forward<U>(handler))
239*3e1bb274SMatthew Barth     {}
240eb639c57SMatthew Barth 
241eb639c57SMatthew Barth     /** @brief Run signal handler function
242eb639c57SMatthew Barth      *
243eb639c57SMatthew Barth      * Extract the property from the InterfacesAdded
244eb639c57SMatthew Barth      * message and run the handler function.
245eb639c57SMatthew Barth      */
246*3e1bb274SMatthew Barth     void operator()(sdbusplus::bus::bus&, sdbusplus::message::message& msg,
247eb639c57SMatthew Barth                     Zone& zone) const
248eb639c57SMatthew Barth     {
249336f18a5SMatthew Barth         if (msg)
250336f18a5SMatthew Barth         {
251eb639c57SMatthew Barth             sdbusplus::message::object_path op;
252eb639c57SMatthew Barth 
253eb639c57SMatthew Barth             msg.read(op);
254d5cfdbe0SMatthew Barth             if (static_cast<const std::string&>(op) != _path)
255eb639c57SMatthew Barth             {
256eb639c57SMatthew Barth                 // Object path does not match this handler's path
257eb639c57SMatthew Barth                 return;
258eb639c57SMatthew Barth             }
259eb639c57SMatthew Barth 
260*3e1bb274SMatthew Barth             std::map<std::string, std::map<std::string, PropertyVariantType>>
261*3e1bb274SMatthew Barth                 intfProp;
262eb639c57SMatthew Barth             msg.read(intfProp);
263469d1366SMatthew Barth             auto itIntf = intfProp.find(_intf);
264eb639c57SMatthew Barth             if (itIntf == intfProp.cend())
265eb639c57SMatthew Barth             {
266eb639c57SMatthew Barth                 // Interface not found on this handler's path
267eb639c57SMatthew Barth                 return;
268eb639c57SMatthew Barth             }
269469d1366SMatthew Barth             auto itProp = itIntf->second.find(_prop);
270eb639c57SMatthew Barth             if (itProp == itIntf->second.cend())
271eb639c57SMatthew Barth             {
272eb639c57SMatthew Barth                 // Property not found on this handler's path
273eb639c57SMatthew Barth                 return;
274eb639c57SMatthew Barth             }
275eb639c57SMatthew Barth 
2767f4c548dSMatthew Barth             // Retrieve the property's value applying any visitors necessary
2777f4c548dSMatthew Barth             auto value =
2787f4c548dSMatthew Barth                 zone.getPropertyValueVisitor<T>(_intf, _prop, itProp->second);
2797f4c548dSMatthew Barth 
2807f4c548dSMatthew Barth             _handler(zone, _path, _intf, _prop, std::forward<T>(value));
281eb639c57SMatthew Barth         }
282336f18a5SMatthew Barth     }
283eb639c57SMatthew Barth 
284eb639c57SMatthew Barth   private:
285eb639c57SMatthew Barth     const char* _path;
286469d1366SMatthew Barth     const char* _intf;
287469d1366SMatthew Barth     const char* _prop;
288eb639c57SMatthew Barth     U _handler;
289eb639c57SMatthew Barth };
290eb639c57SMatthew Barth 
291eb639c57SMatthew Barth /**
292926df663SMatthew Barth  * @brief Used to process a Dbus interfaces added signal event
293eb639c57SMatthew Barth  *
294eb639c57SMatthew Barth  * @param[in] path - Object path
295469d1366SMatthew Barth  * @param[in] intf - Object interface
296469d1366SMatthew Barth  * @param[in] prop - Object property
297eb639c57SMatthew Barth  * @param[in] handler - Handler function to perform
298eb639c57SMatthew Barth  *
299eb639c57SMatthew Barth  * @tparam T - The type of the property
300eb639c57SMatthew Barth  * @tparam U - The type of the handler
301eb639c57SMatthew Barth  */
302eb639c57SMatthew Barth template <typename T, typename U>
303*3e1bb274SMatthew Barth auto interfacesAdded(const char* path, const char* intf, const char* prop,
304eb639c57SMatthew Barth                      U&& handler)
305eb639c57SMatthew Barth {
306*3e1bb274SMatthew Barth     return InterfacesAdded<T, U>(path, intf, prop, std::forward<U>(handler));
307eb639c57SMatthew Barth }
308eb639c57SMatthew Barth 
3098fa02dabSMatthew Barth /**
310469d1366SMatthew Barth  * @struct Interfaces Removed
311469d1366SMatthew Barth  * @brief A match filter functor for Dbus interfaces removed signals
3121499a5c3SMatthew Barth  *
3131499a5c3SMatthew Barth  * @tparam U - The type of the handler
3141499a5c3SMatthew Barth  */
3151499a5c3SMatthew Barth template <typename U>
316469d1366SMatthew Barth struct InterfacesRemoved
3171499a5c3SMatthew Barth {
318469d1366SMatthew Barth     InterfacesRemoved() = delete;
319469d1366SMatthew Barth     ~InterfacesRemoved() = default;
320469d1366SMatthew Barth     InterfacesRemoved(const InterfacesRemoved&) = default;
321469d1366SMatthew Barth     InterfacesRemoved& operator=(const InterfacesRemoved&) = default;
322469d1366SMatthew Barth     InterfacesRemoved(InterfacesRemoved&&) = default;
323469d1366SMatthew Barth     InterfacesRemoved& operator=(InterfacesRemoved&&) = default;
324*3e1bb274SMatthew Barth     InterfacesRemoved(const char* path, const char* intf, U&& handler) :
325*3e1bb274SMatthew Barth         _path(path), _intf(intf), _handler(std::forward<U>(handler))
326*3e1bb274SMatthew Barth     {}
3271499a5c3SMatthew Barth 
3281499a5c3SMatthew Barth     /** @brief Run signal handler function
3291499a5c3SMatthew Barth      *
330469d1366SMatthew Barth      * Extract the interfaces from the InterfacesRemoved
3311499a5c3SMatthew Barth      * message and run the handler function.
3321499a5c3SMatthew Barth      */
333*3e1bb274SMatthew Barth     void operator()(sdbusplus::bus::bus&, sdbusplus::message::message& msg,
3341499a5c3SMatthew Barth                     Zone& zone) const
3351499a5c3SMatthew Barth     {
3361499a5c3SMatthew Barth         if (msg)
3371499a5c3SMatthew Barth         {
3381499a5c3SMatthew Barth             std::vector<std::string> intfs;
3391499a5c3SMatthew Barth             sdbusplus::message::object_path op;
3401499a5c3SMatthew Barth 
3411499a5c3SMatthew Barth             msg.read(op);
3421499a5c3SMatthew Barth             if (static_cast<const std::string&>(op) != _path)
3431499a5c3SMatthew Barth             {
3441499a5c3SMatthew Barth                 // Object path does not match this handler's path
3451499a5c3SMatthew Barth                 return;
3461499a5c3SMatthew Barth             }
3471499a5c3SMatthew Barth 
3481499a5c3SMatthew Barth             msg.read(intfs);
349469d1366SMatthew Barth             auto itIntf = std::find(intfs.begin(), intfs.end(), _intf);
3501499a5c3SMatthew Barth             if (itIntf == intfs.cend())
3511499a5c3SMatthew Barth             {
3521499a5c3SMatthew Barth                 // Interface not found on this handler's path
3531499a5c3SMatthew Barth                 return;
3541499a5c3SMatthew Barth             }
3551499a5c3SMatthew Barth 
3561499a5c3SMatthew Barth             _handler(zone);
3571499a5c3SMatthew Barth         }
3581499a5c3SMatthew Barth     }
3591499a5c3SMatthew Barth 
3601499a5c3SMatthew Barth   private:
3611499a5c3SMatthew Barth     const char* _path;
362469d1366SMatthew Barth     const char* _intf;
3631499a5c3SMatthew Barth     U _handler;
3641499a5c3SMatthew Barth };
3651499a5c3SMatthew Barth 
3661499a5c3SMatthew Barth /**
367926df663SMatthew Barth  * @brief Used to process a Dbus interfaces removed signal event
3681499a5c3SMatthew Barth  *
3691499a5c3SMatthew Barth  * @param[in] path - Object path
370469d1366SMatthew Barth  * @param[in] intf - Object interface
3711499a5c3SMatthew Barth  * @param[in] handler - Handler function to perform
3721499a5c3SMatthew Barth  *
3731499a5c3SMatthew Barth  * @tparam U - The type of the handler
3741499a5c3SMatthew Barth  */
3751499a5c3SMatthew Barth template <typename U>
376*3e1bb274SMatthew Barth auto interfacesRemoved(const char* path, const char* intf, U&& handler)
3771499a5c3SMatthew Barth {
378*3e1bb274SMatthew Barth     return InterfacesRemoved<U>(path, intf, std::forward<U>(handler));
3791499a5c3SMatthew Barth }
3801499a5c3SMatthew Barth 
3811499a5c3SMatthew Barth /**
382926df663SMatthew Barth  * @struct Name Owner
383926df663SMatthew Barth  * @brief A functor for Dbus name owner signals and methods
3848fa02dabSMatthew Barth  *
3858fa02dabSMatthew Barth  * @tparam U - The type of the handler
3868fa02dabSMatthew Barth  */
3878fa02dabSMatthew Barth template <typename U>
388926df663SMatthew Barth struct NameOwner
3898fa02dabSMatthew Barth {
390926df663SMatthew Barth     NameOwner() = delete;
391926df663SMatthew Barth     ~NameOwner() = default;
392926df663SMatthew Barth     NameOwner(const NameOwner&) = default;
393926df663SMatthew Barth     NameOwner& operator=(const NameOwner&) = default;
394926df663SMatthew Barth     NameOwner(NameOwner&&) = default;
395926df663SMatthew Barth     NameOwner& operator=(NameOwner&&) = default;
396*3e1bb274SMatthew Barth     explicit NameOwner(U&& handler) : _handler(std::forward<U>(handler))
397*3e1bb274SMatthew Barth     {}
3988fa02dabSMatthew Barth 
3998fa02dabSMatthew Barth     /** @brief Run signal handler function
4008fa02dabSMatthew Barth      *
4018fa02dabSMatthew Barth      * Extract the name owner from the NameOwnerChanged
402926df663SMatthew Barth      * message and run the handler function.
4038fa02dabSMatthew Barth      */
404*3e1bb274SMatthew Barth     void operator()(sdbusplus::bus::bus& bus, sdbusplus::message::message& msg,
4058fa02dabSMatthew Barth                     Zone& zone) const
4068fa02dabSMatthew Barth     {
4075a302576SMatthew Barth         std::string name;
4085a302576SMatthew Barth         bool hasOwner = false;
4098fa02dabSMatthew Barth         if (msg)
4108fa02dabSMatthew Barth         {
4115a302576SMatthew Barth             // Handle NameOwnerChanged signals
4125a302576SMatthew Barth             msg.read(name);
4135a302576SMatthew Barth 
4145a302576SMatthew Barth             std::string oldOwn;
4155a302576SMatthew Barth             msg.read(oldOwn);
4165a302576SMatthew Barth 
4175a302576SMatthew Barth             std::string newOwn;
4185a302576SMatthew Barth             msg.read(newOwn);
4195a302576SMatthew Barth             if (!newOwn.empty())
4205a302576SMatthew Barth             {
4215a302576SMatthew Barth                 hasOwner = true;
4225a302576SMatthew Barth             }
423926df663SMatthew Barth             _handler(zone, name, hasOwner);
4248fa02dabSMatthew Barth         }
425926df663SMatthew Barth     }
426926df663SMatthew Barth 
427*3e1bb274SMatthew Barth     void operator()(Zone& zone, const Group& group) const
4288fa02dabSMatthew Barth     {
429926df663SMatthew Barth         std::string name = "";
430926df663SMatthew Barth         bool hasOwner = false;
431926df663SMatthew Barth         std::for_each(
432*3e1bb274SMatthew Barth             group.begin(), group.end(),
433*3e1bb274SMatthew Barth             [&zone, &group, &name, &hasOwner,
434*3e1bb274SMatthew Barth              handler = std::move(_handler)](auto const& member) {
435926df663SMatthew Barth                 auto path = std::get<pathPos>(member);
436926df663SMatthew Barth                 auto intf = std::get<intfPos>(member);
4375a302576SMatthew Barth                 try
4385a302576SMatthew Barth                 {
439926df663SMatthew Barth                     auto servName = zone.getService(path, intf);
440926df663SMatthew Barth                     if (name != servName)
441926df663SMatthew Barth                     {
442926df663SMatthew Barth                         name = servName;
4435a302576SMatthew Barth                         hasOwner = util::SDBusPlus::callMethodAndRead<bool>(
444*3e1bb274SMatthew Barth                             zone.getBus(), "org.freedesktop.DBus",
445*3e1bb274SMatthew Barth                             "/org/freedesktop/DBus", "org.freedesktop.DBus",
446*3e1bb274SMatthew Barth                             "NameHasOwner", name);
447926df663SMatthew Barth                         // Update service name owner state list of a group
448926df663SMatthew Barth                         handler(zone, name, hasOwner);
449926df663SMatthew Barth                     }
4508fa02dabSMatthew Barth                 }
451ba7b5feaSMatt Spinler                 catch (const util::DBusMethodError& e)
4525a302576SMatthew Barth                 {
4535a302576SMatthew Barth                     // Failed to get service name owner state
454926df663SMatthew Barth                     name = "";
4555a302576SMatthew Barth                     hasOwner = false;
4565a302576SMatthew Barth                 }
457*3e1bb274SMatthew Barth             });
4588fa02dabSMatthew Barth     }
4598fa02dabSMatthew Barth 
4608fa02dabSMatthew Barth   private:
4618fa02dabSMatthew Barth     U _handler;
4628fa02dabSMatthew Barth };
4638fa02dabSMatthew Barth 
4648fa02dabSMatthew Barth /**
4658fa02dabSMatthew Barth  * @brief Used to process a Dbus name owner changed signal event
4668fa02dabSMatthew Barth  *
4678fa02dabSMatthew Barth  * @param[in] handler - Handler function to perform
4688fa02dabSMatthew Barth  *
4698fa02dabSMatthew Barth  * @tparam U - The type of the handler
4708fa02dabSMatthew Barth  *
4718fa02dabSMatthew Barth  * @return - The NameOwnerChanged signal struct
4728fa02dabSMatthew Barth  */
4738fa02dabSMatthew Barth template <typename U>
474926df663SMatthew Barth auto nameOwnerChanged(U&& handler)
4758fa02dabSMatthew Barth {
476926df663SMatthew Barth     return NameOwner<U>(std::forward<U>(handler));
477926df663SMatthew Barth }
478926df663SMatthew Barth 
479926df663SMatthew Barth /**
480926df663SMatthew Barth  * @brief Used to process the init of a name owner event
481926df663SMatthew Barth  *
482926df663SMatthew Barth  * @param[in] handler - Handler function to perform
483926df663SMatthew Barth  *
484926df663SMatthew Barth  * @tparam U - The type of the handler
485926df663SMatthew Barth  *
486926df663SMatthew Barth  * @return - The NameOwnerChanged signal struct
487926df663SMatthew Barth  */
488926df663SMatthew Barth template <typename U>
489926df663SMatthew Barth auto nameHasOwner(U&& handler)
490926df663SMatthew Barth {
491926df663SMatthew Barth     return NameOwner<U>(std::forward<U>(handler));
4928fa02dabSMatthew Barth }
4938fa02dabSMatthew Barth 
49438a93a8aSMatthew Barth } // namespace control
49538a93a8aSMatthew Barth } // namespace fan
49638a93a8aSMatthew Barth } // namespace phosphor
497