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