1 #pragma once
2 
3 #include "../manager.hpp"
4 
5 #include <sdbusplus/message.hpp>
6 
7 #include <algorithm>
8 #include <map>
9 #include <tuple>
10 #include <vector>
11 
12 namespace phosphor::fan::control::json::trigger::signal
13 {
14 
15 using namespace sdbusplus::message;
16 
17 struct Handlers
18 {
19 
20   public:
21     /**
22      * @brief Processes a properties changed signal and updates the property's
23      * value in the manager's object cache
24      *
25      * @param[in] msg - The sdbusplus signal message
26      * @param[in] obj - Object data associated with the signal
27      * @param[in] mgr - Manager that stores the object cache
28      */
29     static bool propertiesChanged(message& msg, const SignalObject& obj,
30                                   Manager& mgr)
31     {
32         std::string intf;
33         msg.read(intf);
34         if (intf != std::get<Intf>(obj))
35         {
36             // Interface name does not match object's interface
37             return false;
38         }
39 
40         std::map<std::string, PropertyVariantType> props;
41         msg.read(props);
42         auto itProp = props.find(std::get<Prop>(obj));
43         if (itProp == props.cend())
44         {
45             // Object's property not in dictionary of properties changed
46             return false;
47         }
48 
49         mgr.setProperty(std::get<Path>(obj), std::get<Intf>(obj),
50                         std::get<Prop>(obj), itProp->second);
51         return true;
52     }
53 
54     /**
55      * @brief Processes an interfaces added signal and adds the interface
56      * (including property & property value) to the manager's object cache
57      *
58      * @param[in] msg - The sdbusplus signal message
59      * @param[in] obj - Object data associated with the signal
60      * @param[in] mgr - Manager that stores the object cache
61      */
62     static bool interfacesAdded(message& msg, const SignalObject& obj,
63                                 Manager& mgr)
64     {
65         sdbusplus::message::object_path op;
66         msg.read(op);
67         if (static_cast<const std::string&>(op) != std::get<Path>(obj))
68         {
69             // Path name does not match object's path
70             return false;
71         }
72 
73         std::map<std::string, std::map<std::string, PropertyVariantType>>
74             intfProps;
75         msg.read(intfProps);
76         auto itIntf = intfProps.find(std::get<Intf>(obj));
77         if (itIntf == intfProps.cend())
78         {
79             // Object's interface not in dictionary of interfaces added
80             return false;
81         }
82 
83         auto itProp = itIntf->second.find(std::get<Prop>(obj));
84         if (itProp == itIntf->second.cend())
85         {
86             // Object's property not in dictionary of properties of interface
87             return false;
88         }
89 
90         mgr.setProperty(std::get<Path>(obj), std::get<Intf>(obj),
91                         std::get<Prop>(obj), itProp->second);
92         return true;
93     }
94 
95     /**
96      * @brief Processes an interfaces removed signal and removes the interface
97      * (including its properties) from the object cache on the manager
98      *
99      * @param[in] msg - The sdbusplus signal message
100      * @param[in] obj - Object data associated with the signal
101      * @param[in] mgr - Manager that stores the object cache
102      */
103     static bool interfacesRemoved(message& msg, const SignalObject& obj,
104                                   Manager& mgr)
105     {
106         sdbusplus::message::object_path op;
107         msg.read(op);
108         if (static_cast<const std::string&>(op) != std::get<Path>(obj))
109         {
110             // Path name does not match object's path
111             return false;
112         }
113 
114         std::vector<std::string> intfs;
115         msg.read(intfs);
116         auto itIntf =
117             std::find(intfs.begin(), intfs.end(), std::get<Intf>(obj));
118         if (itIntf == intfs.cend())
119         {
120             // Object's interface not in list of interfaces removed
121             return false;
122         }
123 
124         mgr.removeInterface(std::get<Path>(obj), std::get<Intf>(obj));
125         return true;
126     }
127 
128     /**
129      * @brief Processes a name owner changed signal and updates the service's
130      * owner state for all objects/interfaces associated in the cache
131      *
132      * @param[in] msg - The sdbusplus signal message
133      * @param[in] mgr - Manager that stores the service's owner state
134      */
135     static bool nameOwnerChanged(message& msg, const SignalObject&,
136                                  Manager& mgr)
137     {
138         bool hasOwner = false;
139 
140         std::string serv;
141         msg.read(serv);
142 
143         std::string oldOwner;
144         msg.read(oldOwner);
145 
146         std::string newOwner;
147         msg.read(newOwner);
148         if (!newOwner.empty())
149         {
150             hasOwner = true;
151         }
152 
153         mgr.setOwner(serv, hasOwner);
154         return true;
155     }
156 
157     /**
158      * @brief Processes a dbus member signal, there is nothing associated or
159      * any cache to update when this signal is received
160      */
161     static bool member(message&, const SignalObject&, Manager&)
162     {
163         return true;
164     }
165 };
166 
167 } // namespace phosphor::fan::control::json::trigger::signal
168