blob: cb6c4e4ce30ef238f92d4c61f1f2a3d4e8dbc0bf [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 {
Dhruvaraj Subhashchandranfc30e0c2017-09-19 03:59:08 -0500212 //No errors to process.
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500213 return;
214 }
215
216 for (const auto& elem : mapperResponse)
217 {
218 auto method = bus.new_method_call(elem.second.begin()->first.c_str(),
219 elem.first.c_str(),
220 "org.freedesktop.DBus.Properties",
221 "Get");
222 method.append("org.openbmc.Associations");
223 method.append("associations");
224 auto reply = bus.call(method);
225 if (reply.is_method_error())
226 {
227 //do not stop, continue with next elog
228 log<level::ERR>("Error in getting associations");
229 continue;
230 }
231
232 sdbusplus::message::variant<AssociationList> assoc;
233 reply.read(assoc);
234 auto& assocs = assoc.get<AssociationList>();
235 if (assocs.empty())
236 {
237 //no associations, skip
238 continue;
239 }
240
241 for (const auto& item : assocs)
242 {
243 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
244 {
245 removeWatches.emplace_back(
246 std::make_unique<Remove>(bus, std::get<2>(item)));
247 action(bus, std::get<2>(item), true);
248 }
249 }
250 }
251}
252
Patrick Williams3eedbe42017-05-31 17:27:05 -0500253void Remove::removed(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500254{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500255 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500256
Patrick Williams3eedbe42017-05-31 17:27:05 -0500257 action(bus, inventoryPath, false);
258 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500259}
260
261}//namespace monitor
262}//namespace fault
263}//namespace fru
264}//namespace led
265}//namespace phosphor