xref: /openbmc/phosphor-fan-presence/control/functor.hpp (revision 7f4c548dbf7df0f77b9b4672278d56b846f02ccc)
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  */
52926df663SMatthew Barth template <typename T, typename U>
53926df663SMatthew Barth auto make_handler(U&& handler)
5438a93a8aSMatthew Barth {
55926df663SMatthew 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 /**
72926df663SMatthew Barth  * @struct Properties
73926df663SMatthew Barth  * @brief A set of match filter functors for Dbus property values. Each
74926df663SMatthew Barth  * functor provides an associated process for retrieving the value
75926df663SMatthew 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>
81926df663SMatthew Barth struct Properties
8238a93a8aSMatthew Barth {
83926df663SMatthew Barth     Properties() = delete;
84926df663SMatthew Barth     ~Properties() = default;
85926df663SMatthew Barth     Properties(const Properties&) = default;
86926df663SMatthew Barth     Properties& operator=(const Properties&) = default;
87926df663SMatthew Barth     Properties(Properties&&) = default;
88926df663SMatthew Barth     Properties& operator=(Properties&&) = default;
89926df663SMatthew Barth     explicit Properties(U&& handler) :
90926df663SMatthew Barth         _handler(std::forward<U>(handler)) { }
91926df663SMatthew Barth     Properties(const char* path,
92469d1366SMatthew Barth                const char* intf,
93469d1366SMatthew Barth                const char* prop,
9438a93a8aSMatthew Barth                U&& handler) :
95336f18a5SMatthew Barth         _path(path),
96469d1366SMatthew Barth         _intf(intf),
97469d1366SMatthew Barth         _prop(prop),
9838a93a8aSMatthew Barth         _handler(std::forward<U>(handler)) { }
9938a93a8aSMatthew Barth 
10038a93a8aSMatthew Barth     /** @brief Run signal handler function
10138a93a8aSMatthew Barth      *
10238a93a8aSMatthew Barth      * Extract the property from the PropertiesChanged
103926df663SMatthew Barth      * message and run the handler function.
10438a93a8aSMatthew Barth      */
105336f18a5SMatthew Barth     void operator()(sdbusplus::bus::bus& bus,
10638a93a8aSMatthew Barth                     sdbusplus::message::message& msg,
10738a93a8aSMatthew Barth                     Zone& zone) const
10838a93a8aSMatthew Barth     {
109336f18a5SMatthew Barth         if (msg)
110336f18a5SMatthew Barth         {
111469d1366SMatthew Barth             std::string intf;
112469d1366SMatthew Barth             msg.read(intf);
113469d1366SMatthew Barth             if (intf != _intf)
11438a93a8aSMatthew Barth             {
115469d1366SMatthew Barth                 // Interface name does not match on object
11638a93a8aSMatthew Barth                 return;
11738a93a8aSMatthew Barth             }
11838a93a8aSMatthew Barth 
119*7f4c548dSMatthew Barth             std::map<std::string, PropertyVariantType> props;
120469d1366SMatthew Barth             msg.read(props);
121469d1366SMatthew Barth             auto it = props.find(_prop);
122469d1366SMatthew Barth             if (it == props.cend())
12338a93a8aSMatthew Barth             {
124469d1366SMatthew Barth                 // Property not included in dictionary of properties changed
12538a93a8aSMatthew Barth                 return;
12638a93a8aSMatthew Barth             }
12738a93a8aSMatthew Barth 
128*7f4c548dSMatthew Barth             // Retrieve the property's value applying any visitors necessary
129*7f4c548dSMatthew Barth             auto value =
130*7f4c548dSMatthew Barth                 zone.getPropertyValueVisitor<T>(_intf, _prop, it->second);
131*7f4c548dSMatthew Barth 
132*7f4c548dSMatthew Barth             _handler(zone, _path, _intf, _prop, std::forward<T>(value));
13338a93a8aSMatthew Barth         }
134336f18a5SMatthew Barth         else
135336f18a5SMatthew Barth         {
136336f18a5SMatthew Barth             try
137336f18a5SMatthew Barth             {
138469d1366SMatthew Barth                 auto val = zone.getPropertyByName<T>(_path, _intf, _prop);
139469d1366SMatthew Barth                 _handler(zone, _path, _intf, _prop, std::forward<T>(val));
140336f18a5SMatthew Barth             }
14186be476bSMatthew Barth             catch (const sdbusplus::exception::SdBusError&)
14286be476bSMatthew Barth             {
14386be476bSMatthew Barth                 // Property will not be used unless a property changed
14486be476bSMatthew Barth                 // signal message is received for this property.
14586be476bSMatthew Barth             }
14686be476bSMatthew Barth             catch (const util::DBusError&)
147336f18a5SMatthew Barth             {
148336f18a5SMatthew Barth                 // Property will not be used unless a property changed
149336f18a5SMatthew Barth                 // signal message is received for this property.
150336f18a5SMatthew Barth             }
151336f18a5SMatthew Barth         }
152336f18a5SMatthew Barth     }
15338a93a8aSMatthew Barth 
154926df663SMatthew Barth     /** @brief Run init handler function
155926df663SMatthew Barth      *
156926df663SMatthew Barth      * Get the property from each member object of the group
157926df663SMatthew Barth      * and run the handler function.
158926df663SMatthew Barth      */
159926df663SMatthew Barth     void operator()(Zone& zone, const Group& group) const
160926df663SMatthew Barth     {
161926df663SMatthew Barth         std::for_each(
162926df663SMatthew Barth             group.begin(),
163926df663SMatthew Barth             group.end(),
164469d1366SMatthew Barth             [&zone, handler = std::move(_handler)](auto const& member)
165926df663SMatthew Barth             {
166926df663SMatthew Barth                 auto path = std::get<pathPos>(member);
167926df663SMatthew Barth                 auto intf = std::get<intfPos>(member);
168926df663SMatthew Barth                 auto prop = std::get<propPos>(member);
169926df663SMatthew Barth                 try
170926df663SMatthew Barth                 {
171926df663SMatthew Barth                     auto val = zone.getPropertyByName<T>(path, intf, prop);
172469d1366SMatthew Barth                     handler(zone, path, intf, prop, std::forward<T>(val));
173926df663SMatthew Barth                 }
174926df663SMatthew Barth                 catch (const sdbusplus::exception::SdBusError&)
175926df663SMatthew Barth                 {
176926df663SMatthew Barth                     // Property value not sent to handler
177926df663SMatthew Barth                 }
178926df663SMatthew Barth                 catch (const util::DBusError&)
179926df663SMatthew Barth                 {
180926df663SMatthew Barth                     // Property value not sent to handler
181926df663SMatthew Barth                 }
182926df663SMatthew Barth             }
183926df663SMatthew Barth         );
184926df663SMatthew Barth     }
185926df663SMatthew Barth 
18638a93a8aSMatthew Barth private:
187336f18a5SMatthew Barth     const char* _path;
188469d1366SMatthew Barth     const char* _intf;
189469d1366SMatthew Barth     const char* _prop;
19038a93a8aSMatthew Barth     U _handler;
19138a93a8aSMatthew Barth };
19238a93a8aSMatthew Barth 
19338a93a8aSMatthew Barth /**
194469d1366SMatthew Barth  * @brief Used to process a Dbus properties changed signal event
19538a93a8aSMatthew Barth  *
196336f18a5SMatthew Barth  * @param[in] path - Object path
197469d1366SMatthew Barth  * @param[in] intf - Object interface
198469d1366SMatthew Barth  * @param[in] prop - Object property
19938a93a8aSMatthew Barth  * @param[in] handler - Handler function to perform
20038a93a8aSMatthew Barth  *
20138a93a8aSMatthew Barth  * @tparam T - The type of the property
20238a93a8aSMatthew Barth  * @tparam U - The type of the handler
20338a93a8aSMatthew Barth  */
20438a93a8aSMatthew Barth template <typename T, typename U>
205926df663SMatthew Barth auto propertiesChanged(const char* path,
206469d1366SMatthew Barth                        const char* intf,
207469d1366SMatthew Barth                        const char* prop,
20838a93a8aSMatthew Barth                        U&& handler)
20938a93a8aSMatthew Barth {
210926df663SMatthew Barth     return Properties<T, U>(path,
211469d1366SMatthew Barth                             intf,
212469d1366SMatthew Barth                             prop,
213336f18a5SMatthew Barth                             std::forward<U>(handler));
21438a93a8aSMatthew Barth }
21538a93a8aSMatthew Barth 
216eb639c57SMatthew Barth /**
217469d1366SMatthew Barth  * @brief Used to get the properties of an event's group
218926df663SMatthew Barth  *
219926df663SMatthew Barth  * @param[in] handler - Handler function to perform
220926df663SMatthew Barth  *
221469d1366SMatthew Barth  * @tparam T - The type of all the properties
222926df663SMatthew Barth  * @tparam U - The type of the handler
223926df663SMatthew Barth  */
224926df663SMatthew Barth template <typename T, typename U>
225469d1366SMatthew Barth auto getProperties(U&& handler)
226926df663SMatthew Barth {
227926df663SMatthew Barth     return Properties<T, U>(std::forward<U>(handler));
228926df663SMatthew Barth }
229926df663SMatthew Barth 
230926df663SMatthew Barth /**
231469d1366SMatthew Barth  * @struct Interfaces Added
232469d1366SMatthew Barth  * @brief A match filter functor for Dbus interfaces added signals
233eb639c57SMatthew Barth  *
234eb639c57SMatthew Barth  * @tparam T - The type of the property value
235eb639c57SMatthew Barth  * @tparam U - The type of the handler
236eb639c57SMatthew Barth  */
237eb639c57SMatthew Barth template <typename T, typename U>
238469d1366SMatthew Barth struct InterfacesAdded
239eb639c57SMatthew Barth {
240469d1366SMatthew Barth     InterfacesAdded() = delete;
241469d1366SMatthew Barth     ~InterfacesAdded() = default;
242469d1366SMatthew Barth     InterfacesAdded(const InterfacesAdded&) = default;
243469d1366SMatthew Barth     InterfacesAdded& operator=(const InterfacesAdded&) = default;
244469d1366SMatthew Barth     InterfacesAdded(InterfacesAdded&&) = default;
245469d1366SMatthew Barth     InterfacesAdded& operator=(InterfacesAdded&&) = default;
246469d1366SMatthew Barth     InterfacesAdded(const char* path,
247469d1366SMatthew Barth                     const char* intf,
248469d1366SMatthew Barth                     const char* prop,
249eb639c57SMatthew Barth                     U&& handler) :
250eb639c57SMatthew Barth         _path(path),
251469d1366SMatthew Barth         _intf(intf),
252469d1366SMatthew Barth         _prop(prop),
253eb639c57SMatthew Barth         _handler(std::forward<U>(handler)) { }
254eb639c57SMatthew Barth 
255eb639c57SMatthew Barth     /** @brief Run signal handler function
256eb639c57SMatthew Barth      *
257eb639c57SMatthew Barth      * Extract the property from the InterfacesAdded
258eb639c57SMatthew Barth      * message and run the handler function.
259eb639c57SMatthew Barth      */
260eb639c57SMatthew Barth     void operator()(sdbusplus::bus::bus&,
261eb639c57SMatthew Barth                     sdbusplus::message::message& msg,
262eb639c57SMatthew Barth                     Zone& zone) const
263eb639c57SMatthew Barth     {
264336f18a5SMatthew Barth         if (msg)
265336f18a5SMatthew Barth         {
266eb639c57SMatthew Barth             sdbusplus::message::object_path op;
267eb639c57SMatthew Barth 
268eb639c57SMatthew Barth             msg.read(op);
269d5cfdbe0SMatthew Barth             if (static_cast<const std::string&>(op) != _path)
270eb639c57SMatthew Barth             {
271eb639c57SMatthew Barth                 // Object path does not match this handler's path
272eb639c57SMatthew Barth                 return;
273eb639c57SMatthew Barth             }
274eb639c57SMatthew Barth 
275*7f4c548dSMatthew Barth             std::map<std::string, std::map<std::string,
276*7f4c548dSMatthew Barth                     PropertyVariantType>> intfProp;
277eb639c57SMatthew Barth             msg.read(intfProp);
278469d1366SMatthew Barth             auto itIntf = intfProp.find(_intf);
279eb639c57SMatthew Barth             if (itIntf == intfProp.cend())
280eb639c57SMatthew Barth             {
281eb639c57SMatthew Barth                 // Interface not found on this handler's path
282eb639c57SMatthew Barth                 return;
283eb639c57SMatthew Barth             }
284469d1366SMatthew Barth             auto itProp = itIntf->second.find(_prop);
285eb639c57SMatthew Barth             if (itProp == itIntf->second.cend())
286eb639c57SMatthew Barth             {
287eb639c57SMatthew Barth                 // Property not found on this handler's path
288eb639c57SMatthew Barth                 return;
289eb639c57SMatthew Barth             }
290eb639c57SMatthew Barth 
291*7f4c548dSMatthew Barth             // Retrieve the property's value applying any visitors necessary
292*7f4c548dSMatthew Barth             auto value =
293*7f4c548dSMatthew Barth                 zone.getPropertyValueVisitor<T>(_intf, _prop, itProp->second);
294*7f4c548dSMatthew Barth 
295*7f4c548dSMatthew Barth             _handler(zone, _path, _intf, _prop, std::forward<T>(value));
296eb639c57SMatthew Barth         }
297336f18a5SMatthew Barth     }
298eb639c57SMatthew Barth 
299eb639c57SMatthew Barth private:
300eb639c57SMatthew Barth     const char* _path;
301469d1366SMatthew Barth     const char* _intf;
302469d1366SMatthew Barth     const char* _prop;
303eb639c57SMatthew Barth     U _handler;
304eb639c57SMatthew Barth };
305eb639c57SMatthew Barth 
306eb639c57SMatthew Barth /**
307926df663SMatthew Barth  * @brief Used to process a Dbus interfaces added signal event
308eb639c57SMatthew Barth  *
309eb639c57SMatthew Barth  * @param[in] path - Object path
310469d1366SMatthew Barth  * @param[in] intf - Object interface
311469d1366SMatthew Barth  * @param[in] prop - Object property
312eb639c57SMatthew Barth  * @param[in] handler - Handler function to perform
313eb639c57SMatthew Barth  *
314eb639c57SMatthew Barth  * @tparam T - The type of the property
315eb639c57SMatthew Barth  * @tparam U - The type of the handler
316eb639c57SMatthew Barth  */
317eb639c57SMatthew Barth template <typename T, typename U>
318926df663SMatthew Barth auto interfacesAdded(const char* path,
319469d1366SMatthew Barth                      const char* intf,
320469d1366SMatthew Barth                      const char* prop,
321eb639c57SMatthew Barth                      U&& handler)
322eb639c57SMatthew Barth {
323469d1366SMatthew Barth     return InterfacesAdded<T, U>(path,
324469d1366SMatthew Barth                                  intf,
325469d1366SMatthew Barth                                  prop,
326eb639c57SMatthew Barth                                  std::forward<U>(handler));
327eb639c57SMatthew Barth }
328eb639c57SMatthew Barth 
3298fa02dabSMatthew Barth /**
330469d1366SMatthew Barth  * @struct Interfaces Removed
331469d1366SMatthew Barth  * @brief A match filter functor for Dbus interfaces removed signals
3321499a5c3SMatthew Barth  *
3331499a5c3SMatthew Barth  * @tparam U - The type of the handler
3341499a5c3SMatthew Barth  */
3351499a5c3SMatthew Barth template <typename U>
336469d1366SMatthew Barth struct InterfacesRemoved
3371499a5c3SMatthew Barth {
338469d1366SMatthew Barth     InterfacesRemoved() = delete;
339469d1366SMatthew Barth     ~InterfacesRemoved() = default;
340469d1366SMatthew Barth     InterfacesRemoved(const InterfacesRemoved&) = default;
341469d1366SMatthew Barth     InterfacesRemoved& operator=(const InterfacesRemoved&) = default;
342469d1366SMatthew Barth     InterfacesRemoved(InterfacesRemoved&&) = default;
343469d1366SMatthew Barth     InterfacesRemoved& operator=(InterfacesRemoved&&) = default;
344469d1366SMatthew Barth     InterfacesRemoved(const char* path,
345469d1366SMatthew Barth                       const char* intf,
3461499a5c3SMatthew Barth                       U&& handler) :
3471499a5c3SMatthew Barth         _path(path),
348469d1366SMatthew Barth         _intf(intf),
3491499a5c3SMatthew Barth         _handler(std::forward<U>(handler)) { }
3501499a5c3SMatthew Barth 
3511499a5c3SMatthew Barth     /** @brief Run signal handler function
3521499a5c3SMatthew Barth      *
353469d1366SMatthew Barth      * Extract the interfaces from the InterfacesRemoved
3541499a5c3SMatthew Barth      * message and run the handler function.
3551499a5c3SMatthew Barth      */
3561499a5c3SMatthew Barth     void operator()(sdbusplus::bus::bus&,
3571499a5c3SMatthew Barth                     sdbusplus::message::message& msg,
3581499a5c3SMatthew Barth                     Zone& zone) const
3591499a5c3SMatthew Barth     {
3601499a5c3SMatthew Barth         if (msg)
3611499a5c3SMatthew Barth         {
3621499a5c3SMatthew Barth             std::vector<std::string> intfs;
3631499a5c3SMatthew Barth             sdbusplus::message::object_path op;
3641499a5c3SMatthew Barth 
3651499a5c3SMatthew Barth             msg.read(op);
3661499a5c3SMatthew Barth             if (static_cast<const std::string&>(op) != _path)
3671499a5c3SMatthew Barth             {
3681499a5c3SMatthew Barth                 // Object path does not match this handler's path
3691499a5c3SMatthew Barth                 return;
3701499a5c3SMatthew Barth             }
3711499a5c3SMatthew Barth 
3721499a5c3SMatthew Barth             msg.read(intfs);
373469d1366SMatthew Barth             auto itIntf = std::find(intfs.begin(), intfs.end(), _intf);
3741499a5c3SMatthew Barth             if (itIntf == intfs.cend())
3751499a5c3SMatthew Barth             {
3761499a5c3SMatthew Barth                 // Interface not found on this handler's path
3771499a5c3SMatthew Barth                 return;
3781499a5c3SMatthew Barth             }
3791499a5c3SMatthew Barth 
3801499a5c3SMatthew Barth             _handler(zone);
3811499a5c3SMatthew Barth         }
3821499a5c3SMatthew Barth     }
3831499a5c3SMatthew Barth 
3841499a5c3SMatthew Barth private:
3851499a5c3SMatthew Barth     const char* _path;
386469d1366SMatthew Barth     const char* _intf;
3871499a5c3SMatthew Barth     U _handler;
3881499a5c3SMatthew Barth };
3891499a5c3SMatthew Barth 
3901499a5c3SMatthew Barth /**
391926df663SMatthew Barth  * @brief Used to process a Dbus interfaces removed signal event
3921499a5c3SMatthew Barth  *
3931499a5c3SMatthew Barth  * @param[in] path - Object path
394469d1366SMatthew Barth  * @param[in] intf - Object interface
3951499a5c3SMatthew Barth  * @param[in] handler - Handler function to perform
3961499a5c3SMatthew Barth  *
3971499a5c3SMatthew Barth  * @tparam U - The type of the handler
3981499a5c3SMatthew Barth  */
3991499a5c3SMatthew Barth template <typename U>
400926df663SMatthew Barth auto interfacesRemoved(const char* path,
401469d1366SMatthew Barth                        const char* intf,
4021499a5c3SMatthew Barth                        U&& handler)
4031499a5c3SMatthew Barth {
404469d1366SMatthew Barth     return InterfacesRemoved<U>(path,
405469d1366SMatthew Barth                                 intf,
4061499a5c3SMatthew Barth                                 std::forward<U>(handler));
4071499a5c3SMatthew Barth }
4081499a5c3SMatthew Barth 
4091499a5c3SMatthew Barth /**
410926df663SMatthew Barth  * @struct Name Owner
411926df663SMatthew Barth  * @brief A functor for Dbus name owner signals and methods
4128fa02dabSMatthew Barth  *
4138fa02dabSMatthew Barth  * @tparam U - The type of the handler
4148fa02dabSMatthew Barth  */
4158fa02dabSMatthew Barth template <typename U>
416926df663SMatthew Barth struct NameOwner
4178fa02dabSMatthew Barth {
418926df663SMatthew Barth     NameOwner() = delete;
419926df663SMatthew Barth     ~NameOwner() = default;
420926df663SMatthew Barth     NameOwner(const NameOwner&) = default;
421926df663SMatthew Barth     NameOwner& operator=(const NameOwner&) = default;
422926df663SMatthew Barth     NameOwner(NameOwner&&) = default;
423926df663SMatthew Barth     NameOwner& operator=(NameOwner&&) = default;
424926df663SMatthew Barth     explicit NameOwner(U&& handler) :
4258fa02dabSMatthew Barth         _handler(std::forward<U>(handler)) { }
4268fa02dabSMatthew Barth 
4278fa02dabSMatthew Barth     /** @brief Run signal handler function
4288fa02dabSMatthew Barth      *
4298fa02dabSMatthew Barth      * Extract the name owner from the NameOwnerChanged
430926df663SMatthew Barth      * message and run the handler function.
4318fa02dabSMatthew Barth      */
4328fa02dabSMatthew Barth     void operator()(sdbusplus::bus::bus& bus,
4338fa02dabSMatthew Barth                     sdbusplus::message::message& msg,
4348fa02dabSMatthew Barth                     Zone& zone) const
4358fa02dabSMatthew Barth     {
4365a302576SMatthew Barth         std::string name;
4375a302576SMatthew Barth         bool hasOwner = false;
4388fa02dabSMatthew Barth         if (msg)
4398fa02dabSMatthew Barth         {
4405a302576SMatthew Barth             // Handle NameOwnerChanged signals
4415a302576SMatthew Barth             msg.read(name);
4425a302576SMatthew Barth 
4435a302576SMatthew Barth             std::string oldOwn;
4445a302576SMatthew Barth             msg.read(oldOwn);
4455a302576SMatthew Barth 
4465a302576SMatthew Barth             std::string newOwn;
4475a302576SMatthew Barth             msg.read(newOwn);
4485a302576SMatthew Barth             if (!newOwn.empty())
4495a302576SMatthew Barth             {
4505a302576SMatthew Barth                 hasOwner = true;
4515a302576SMatthew Barth             }
452926df663SMatthew Barth             _handler(zone, name, hasOwner);
4538fa02dabSMatthew Barth         }
454926df663SMatthew Barth     }
455926df663SMatthew Barth 
456926df663SMatthew Barth     void operator()(Zone& zone,
457926df663SMatthew Barth                     const Group& group) const
4588fa02dabSMatthew Barth     {
459926df663SMatthew Barth         std::string name = "";
460926df663SMatthew Barth         bool hasOwner = false;
461926df663SMatthew Barth         std::for_each(
462926df663SMatthew Barth             group.begin(),
463926df663SMatthew Barth             group.end(),
464926df663SMatthew Barth             [&zone, &group, &name, &hasOwner, handler = std::move(_handler)](
465926df663SMatthew Barth                 auto const& member)
466926df663SMatthew Barth             {
467926df663SMatthew Barth                 auto path = std::get<pathPos>(member);
468926df663SMatthew Barth                 auto intf = std::get<intfPos>(member);
4695a302576SMatthew Barth                 try
4705a302576SMatthew Barth                 {
471926df663SMatthew Barth                     auto servName = zone.getService(path, intf);
472926df663SMatthew Barth                     if (name != servName)
473926df663SMatthew Barth                     {
474926df663SMatthew Barth                         name = servName;
4755a302576SMatthew Barth                         hasOwner = util::SDBusPlus::callMethodAndRead<bool>(
476926df663SMatthew Barth                                 zone.getBus(),
4775a302576SMatthew Barth                                 "org.freedesktop.DBus",
4785a302576SMatthew Barth                                 "/org/freedesktop/DBus",
4795a302576SMatthew Barth                                 "org.freedesktop.DBus",
4805a302576SMatthew Barth                                 "NameHasOwner",
4815a302576SMatthew Barth                                 name);
482926df663SMatthew Barth                         // Update service name owner state list of a group
483926df663SMatthew Barth                         handler(zone, name, hasOwner);
484926df663SMatthew Barth                     }
4858fa02dabSMatthew Barth                 }
486ba7b5feaSMatt Spinler                 catch (const util::DBusMethodError& e)
4875a302576SMatthew Barth                 {
4885a302576SMatthew Barth                     // Failed to get service name owner state
489926df663SMatthew Barth                     name = "";
4905a302576SMatthew Barth                     hasOwner = false;
4915a302576SMatthew Barth                 }
492926df663SMatthew Barth             }
493926df663SMatthew Barth         );
4948fa02dabSMatthew Barth     }
4958fa02dabSMatthew Barth 
4968fa02dabSMatthew Barth private:
4978fa02dabSMatthew Barth     U _handler;
4988fa02dabSMatthew Barth };
4998fa02dabSMatthew Barth 
5008fa02dabSMatthew Barth /**
5018fa02dabSMatthew Barth  * @brief Used to process a Dbus name owner changed signal event
5028fa02dabSMatthew Barth  *
5038fa02dabSMatthew Barth  * @param[in] handler - Handler function to perform
5048fa02dabSMatthew Barth  *
5058fa02dabSMatthew Barth  * @tparam U - The type of the handler
5068fa02dabSMatthew Barth  *
5078fa02dabSMatthew Barth  * @return - The NameOwnerChanged signal struct
5088fa02dabSMatthew Barth  */
5098fa02dabSMatthew Barth template <typename U>
510926df663SMatthew Barth auto nameOwnerChanged(U&& handler)
5118fa02dabSMatthew Barth {
512926df663SMatthew Barth     return NameOwner<U>(std::forward<U>(handler));
513926df663SMatthew Barth }
514926df663SMatthew Barth 
515926df663SMatthew Barth /**
516926df663SMatthew Barth  * @brief Used to process the init of a name owner event
517926df663SMatthew Barth  *
518926df663SMatthew Barth  * @param[in] handler - Handler function to perform
519926df663SMatthew Barth  *
520926df663SMatthew Barth  * @tparam U - The type of the handler
521926df663SMatthew Barth  *
522926df663SMatthew Barth  * @return - The NameOwnerChanged signal struct
523926df663SMatthew Barth  */
524926df663SMatthew Barth template <typename U>
525926df663SMatthew Barth auto nameHasOwner(U&& handler)
526926df663SMatthew Barth {
527926df663SMatthew Barth     return NameOwner<U>(std::forward<U>(handler));
5288fa02dabSMatthew Barth }
5298fa02dabSMatthew Barth 
53038a93a8aSMatthew Barth } // namespace control
53138a93a8aSMatthew Barth } // namespace fan
53238a93a8aSMatthew Barth } // namespace phosphor
533