blob: e21727b48101dd70466230dd3a0dc572443e571c [file] [log] [blame]
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -05001#include <phosphor-logging/elog.hpp>
2#include "xyz/openbmc_project/Led/Fru/Monitor/error.hpp"
3#include "xyz/openbmc_project/Led/Mapper/error.hpp"
4#include "elog-errors.hpp"
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -05005#include "fru-fault-monitor.hpp"
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -05006
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -05007namespace phosphor
8{
9namespace led
10{
11namespace fru
12{
13namespace fault
14{
15namespace monitor
16{
17
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050018using namespace phosphor::logging;
19
20constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
21constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper";
22constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper";
23constexpr auto OBJMGR_IFACE = "org.freedesktop.DBus.ObjectManager";
24constexpr auto LED_GROUPS = "/xyz/openbmc_project/led/groups/";
25constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
26
27using AssociationList = std::vector<std::tuple<
28 std::string, std::string, std::string>>;
29using MethodErr =
30 sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
31using ObjectNotFoundErr =
32 sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
33using AssociationRetrieveErr =
34 sdbusplus::xyz::openbmc_project::
35 Led::Fru::Monitor::Error::AssociationRetrieveError;
36using InventoryPathErr =
37 sdbusplus::xyz::openbmc_project::
38 Led::Fru::Monitor::Error::InventoryPathError;
39
40std::string getService(sdbusplus::bus::bus& bus,
41 const std::string& path)
42{
43 auto mapper = bus.new_method_call(MAPPER_BUSNAME,
44 MAPPER_OBJ_PATH,
45 MAPPER_IFACE, "GetObject");
46 mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
47 auto mapperResponseMsg = bus.call(mapper);
48 if (mapperResponseMsg.is_method_error())
49 {
50 using namespace xyz::openbmc_project::Led::Mapper;
51 elog<MethodErr>(
52 MethodError::METHOD_NAME("GetObject"),
53 MethodError::PATH(path.c_str()),
54 MethodError::INTERFACE(
55 OBJMGR_IFACE));
56 }
57
58 std::map<std::string, std::vector<std::string>> mapperResponse;
59 mapperResponseMsg.read(mapperResponse);
60 if (mapperResponse.empty())
61 {
62 using namespace xyz::openbmc_project::Led::Mapper;
63 elog<ObjectNotFoundErr>(
64 ObjectNotFoundError::METHOD_NAME("GetObject"),
65 ObjectNotFoundError::PATH(path.c_str()),
66 ObjectNotFoundError::INTERFACE(
67 OBJMGR_IFACE));
68 }
69
70 return mapperResponse.cbegin()->first;
71}
72
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -050073void action(sdbusplus::bus::bus& bus,
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050074 const std::string& path,
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -050075 bool assert)
76{
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050077 std::string service;
78 try
79 {
80 service = getService(bus, LED_GROUPS);
81 }
82 catch (MethodErr& e)
83 {
84 commit<MethodErr>();
85 return;
86 }
87 catch (ObjectNotFoundErr& e)
88 {
89 commit<ObjectNotFoundErr>();
90 return;
91 }
92
93 auto pos = path.rfind("/");
94 if (pos == std::string::npos)
95 {
96 using namespace xyz::openbmc_project::Led::Fru::Monitor;
97 report<InventoryPathErr>(
98 InventoryPathError::PATH(
99 path.c_str()));
100 return;
101 }
102 auto unit = path.substr(pos + 1);
103
104 std::string ledPath = LED_GROUPS +
105 unit + '_' + LED_FAULT;
106
107 auto method = bus.new_method_call(service.c_str(),
108 ledPath.c_str(),
109 "org.freedesktop.DBus.Properties",
110 "Set");
111 method.append("xyz.openbmc_project.Led.Group");
112 method.append("Asserted");
113
114 method.append(sdbusplus::message::variant<bool>(assert));
115 bus.call_noreply(method);
116
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500117 return;
118}
119
120int Add::created(sd_bus_message* msg,
121 void* data,
122 sd_bus_error* retError)
123{
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500124 auto m = sdbusplus::message::message(msg);
125 auto bus = m.get_bus();
126
127 sdbusplus::message::object_path obPath;
128 m.read(obPath);
129 std::string objectPath(std::move(obPath));
130
131 std::size_t found = objectPath.find(ELOG_ENTRY);
132 if (found == std::string::npos)
133 {
134 //Not a new error entry skip
135 return 0;
136 }
137
138 std::string service;
139 try
140 {
141 service = getService(bus, LOG_PATH);
142 }
143 catch (MethodErr& e)
144 {
145 commit<MethodErr>();
146 return 0;
147 }
148 catch (ObjectNotFoundErr& e)
149 {
150 commit<ObjectNotFoundErr>();
151 return 0;
152 }
153
154 auto method = bus.new_method_call(service.c_str(), objectPath.c_str(),
155 "org.freedesktop.DBus.Properties",
156 "Get");
157
158 method.append("org.openbmc.Associations");
159 method.append("associations");
160 auto reply = bus.call(method);
161 if (reply.is_method_error())
162 {
163 using namespace xyz::openbmc_project::Led::Fru::Monitor;
164 report<AssociationRetrieveErr>(
165 AssociationRetrieveError::ELOG_ENTRY_PATH(
166 objectPath.c_str()));
167 return 0;
168 }
169
170 sdbusplus::message::variant<AssociationList> assoc;
171 reply.read(assoc);
172
173 auto assocs =
174 sdbusplus::message::variant_ns::get<AssociationList>(assoc);
175 if (assocs.empty())
176 {
177 //No associations skip
178 return 0;
179 }
180
181 for (const auto& item : assocs)
182 {
183 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
184 {
185 action(bus, std::get<2>(item), true);
186 static_cast<Add*>(data)->removeWatches.emplace_back(
187 std::make_unique<Remove>(bus, std::get<2>(item)));
188 }
189 }
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500190 return 0;
191}
192
193int Remove::removed(sd_bus_message* msg,
194 void* data,
195 sd_bus_error* retError)
196{
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500197 auto m = sdbusplus::message::message(msg);
198 auto bus = m.get_bus();
199 std::string assoc;
200 m.read(assoc);
201
202 if (assoc.compare("org.openbmc.Association"))
203 {
204 //Skip if not about association
205 return 0;
206 }
207
208 std::map<std::string, std::vector<std::string>> endPoints;
209 m.read(endPoints);
210 auto it = endPoints.find("endpoints");
211
212 if (it == endPoints.end())
213 {
214 //No end points,skip
215 return 0;
216 }
217
218 if (!((*it).second.empty()))
219 {
220 //Skip, end points are not empty
221 return 0;
222 }
223
224 action(bus, static_cast<Remove*>(data)->inventoryPath, false);
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500225 return 0;
226}
227
228}//namespace monitor
229}//namespace fault
230}//namespace fru
231}//namespace led
232}//namespace phosphor