blob: 4b744628469667259b255d00e267fcf8117e1f1b [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 Subhashchandran891c4762017-07-31 14:26:37 -05006#include <phosphor-logging/elog-errors.hpp>
7#include "xyz/openbmc_project/Common/error.hpp"
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -05008
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -05009namespace phosphor
10{
11namespace led
12{
13namespace fru
14{
15namespace fault
16{
17namespace monitor
18{
19
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050020using namespace phosphor::logging;
21
22constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
23constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper";
24constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper";
25constexpr auto OBJMGR_IFACE = "org.freedesktop.DBus.ObjectManager";
26constexpr auto LED_GROUPS = "/xyz/openbmc_project/led/groups/";
27constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -050028constexpr auto LOG_IFACE = "xyz.openbmc_project.Logging.Entry";
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050029
30using AssociationList = std::vector<std::tuple<
31 std::string, std::string, std::string>>;
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -050032using Attributes = sdbusplus::message::variant<bool,AssociationList>;
33using AttributeName = std::string;
34using AttributeMap = std::map<AttributeName, Attributes>;
35using PropertyName = std::string;
36using PropertyMap = std::map<PropertyName, AttributeMap>;
37using LogEntryMsg = std::pair<sdbusplus::message::object_path, PropertyMap>;
38
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -050039using Service = std::string;
40using Path = std::string;
41using Interface = std::string;
42using Interfaces = std::vector<Interface>;
43using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
44
45using InternalFailure =
46 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
47
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050048using MethodErr =
49 sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
50using ObjectNotFoundErr =
51 sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050052using InventoryPathErr =
53 sdbusplus::xyz::openbmc_project::
54 Led::Fru::Monitor::Error::InventoryPathError;
55
56std::string getService(sdbusplus::bus::bus& bus,
57 const std::string& path)
58{
59 auto mapper = bus.new_method_call(MAPPER_BUSNAME,
60 MAPPER_OBJ_PATH,
61 MAPPER_IFACE, "GetObject");
62 mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
63 auto mapperResponseMsg = bus.call(mapper);
64 if (mapperResponseMsg.is_method_error())
65 {
66 using namespace xyz::openbmc_project::Led::Mapper;
67 elog<MethodErr>(
68 MethodError::METHOD_NAME("GetObject"),
69 MethodError::PATH(path.c_str()),
70 MethodError::INTERFACE(
71 OBJMGR_IFACE));
72 }
73
74 std::map<std::string, std::vector<std::string>> mapperResponse;
75 mapperResponseMsg.read(mapperResponse);
76 if (mapperResponse.empty())
77 {
78 using namespace xyz::openbmc_project::Led::Mapper;
79 elog<ObjectNotFoundErr>(
80 ObjectNotFoundError::METHOD_NAME("GetObject"),
81 ObjectNotFoundError::PATH(path.c_str()),
82 ObjectNotFoundError::INTERFACE(
83 OBJMGR_IFACE));
84 }
85
86 return mapperResponse.cbegin()->first;
87}
88
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -050089void action(sdbusplus::bus::bus& bus,
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050090 const std::string& path,
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -050091 bool assert)
92{
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -050093 std::string service;
94 try
95 {
96 service = getService(bus, LED_GROUPS);
97 }
98 catch (MethodErr& e)
99 {
100 commit<MethodErr>();
101 return;
102 }
103 catch (ObjectNotFoundErr& e)
104 {
105 commit<ObjectNotFoundErr>();
106 return;
107 }
108
109 auto pos = path.rfind("/");
110 if (pos == std::string::npos)
111 {
112 using namespace xyz::openbmc_project::Led::Fru::Monitor;
113 report<InventoryPathErr>(
114 InventoryPathError::PATH(
115 path.c_str()));
116 return;
117 }
118 auto unit = path.substr(pos + 1);
119
120 std::string ledPath = LED_GROUPS +
121 unit + '_' + LED_FAULT;
122
123 auto method = bus.new_method_call(service.c_str(),
124 ledPath.c_str(),
125 "org.freedesktop.DBus.Properties",
126 "Set");
127 method.append("xyz.openbmc_project.Led.Group");
128 method.append("Asserted");
129
130 method.append(sdbusplus::message::variant<bool>(assert));
131 bus.call_noreply(method);
132
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500133 return;
134}
135
Patrick Williams3eedbe42017-05-31 17:27:05 -0500136void Add::created(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500137{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500138 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500139
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500140 LogEntryMsg logEntry;
141 msg.read(logEntry);
142 std::string objectPath(std::move(logEntry.first));
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500143
144 std::size_t found = objectPath.find(ELOG_ENTRY);
145 if (found == std::string::npos)
146 {
147 //Not a new error entry skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500148 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500149 }
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500150 log<level::ERR>(objectPath.c_str());
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500151
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500152 auto iter = logEntry.second.find("org.openbmc.Associations");
153 if (iter == logEntry.second.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500154 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500155 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500156 }
157
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500158 auto attr = iter->second.find("associations");
159 if (attr == iter->second.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500160 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500161 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500162 }
163
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500164 auto& assocs =
165 sdbusplus::message::variant_ns::get<AssociationList>(attr->second);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500166 if (assocs.empty())
167 {
168 //No associations skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500169 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500170 }
171
172 for (const auto& item : assocs)
173 {
174 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
175 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500176 removeWatches.emplace_back(
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500177 std::make_unique<Remove>(bus, std::get<2>(item)));
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500178 action(bus, std::get<2>(item), true);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500179 }
180 }
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500181
Patrick Williams3eedbe42017-05-31 17:27:05 -0500182 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500183}
184
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500185void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
186{
187 auto depth = 0;
188 auto mapperCall = bus.new_method_call(MAPPER_BUSNAME,
189 MAPPER_OBJ_PATH,
190 MAPPER_IFACE,
191 "GetSubTree");
192 mapperCall.append("/");
193 mapperCall.append(depth);
194 mapperCall.append(std::vector<Interface>({LOG_IFACE}));
195
196 auto mapperResponseMsg = bus.call(mapperCall);
197 if (mapperResponseMsg.is_method_error())
198 {
199 using namespace xyz::openbmc_project::Led::Mapper;
200 report<MethodErr>(
201 MethodError::METHOD_NAME("GetSubTree"),
202 MethodError::PATH(MAPPER_OBJ_PATH),
203 MethodError::INTERFACE(
204 OBJMGR_IFACE));
205 return;
206 }
207
208 MapperResponseType mapperResponse;
209 mapperResponseMsg.read(mapperResponse);
210 if (mapperResponse.empty())
211 {
212 using namespace xyz::openbmc_project::Led::Mapper;
213 report<ObjectNotFoundErr>(
214 ObjectNotFoundError::METHOD_NAME("GetSubTree"),
215 ObjectNotFoundError::PATH(MAPPER_OBJ_PATH),
216 ObjectNotFoundError::INTERFACE(
217 OBJMGR_IFACE));
218 return;
219 }
220
221 for (const auto& elem : mapperResponse)
222 {
223 auto method = bus.new_method_call(elem.second.begin()->first.c_str(),
224 elem.first.c_str(),
225 "org.freedesktop.DBus.Properties",
226 "Get");
227 method.append("org.openbmc.Associations");
228 method.append("associations");
229 auto reply = bus.call(method);
230 if (reply.is_method_error())
231 {
232 //do not stop, continue with next elog
233 log<level::ERR>("Error in getting associations");
234 continue;
235 }
236
237 sdbusplus::message::variant<AssociationList> assoc;
238 reply.read(assoc);
239 auto& assocs = assoc.get<AssociationList>();
240 if (assocs.empty())
241 {
242 //no associations, skip
243 continue;
244 }
245
246 for (const auto& item : assocs)
247 {
248 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
249 {
250 removeWatches.emplace_back(
251 std::make_unique<Remove>(bus, std::get<2>(item)));
252 action(bus, std::get<2>(item), true);
253 }
254 }
255 }
256}
257
Patrick Williams3eedbe42017-05-31 17:27:05 -0500258void Remove::removed(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500259{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500260 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500261 std::string assoc;
Patrick Williams3eedbe42017-05-31 17:27:05 -0500262 msg.read(assoc);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500263
264 if (assoc.compare("org.openbmc.Association"))
265 {
266 //Skip if not about association
Patrick Williams3eedbe42017-05-31 17:27:05 -0500267 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500268 }
269
270 std::map<std::string, std::vector<std::string>> endPoints;
Patrick Williams3eedbe42017-05-31 17:27:05 -0500271 msg.read(endPoints);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500272 auto it = endPoints.find("endpoints");
273
274 if (it == endPoints.end())
275 {
276 //No end points,skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500277 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500278 }
279
280 if (!((*it).second.empty()))
281 {
282 //Skip, end points are not empty
Patrick Williams3eedbe42017-05-31 17:27:05 -0500283 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500284 }
285
Patrick Williams3eedbe42017-05-31 17:27:05 -0500286 action(bus, inventoryPath, false);
287 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500288}
289
290}//namespace monitor
291}//namespace fault
292}//namespace fru
293}//namespace led
294}//namespace phosphor