blob: 4a600f75ec2da9ab0ac12de895b7e00c4a25922f [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 auto iter = logEntry.second.find("org.openbmc.Associations");
151 if (iter == logEntry.second.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500152 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500153 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500154 }
155
Matt Spinler3d2b0d62018-03-29 08:48:37 -0500156 //Nothing else shows when a specific error log
157 //has been created. Do it here.
158 std::string message{objectPath + " created"};
159 log<level::INFO>(message.c_str());
160
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500161 auto attr = iter->second.find("associations");
162 if (attr == iter->second.end())
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500163 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500164 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500165 }
166
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500167 auto& assocs =
168 sdbusplus::message::variant_ns::get<AssociationList>(attr->second);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500169 if (assocs.empty())
170 {
171 //No associations skip
Patrick Williams3eedbe42017-05-31 17:27:05 -0500172 return;
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500173 }
174
175 for (const auto& item : assocs)
176 {
177 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
178 {
Patrick Williams3eedbe42017-05-31 17:27:05 -0500179 removeWatches.emplace_back(
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500180 std::make_unique<Remove>(bus, std::get<2>(item)));
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500181 action(bus, std::get<2>(item), true);
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500182 }
183 }
Dhruvaraj Subhashchandranaebfde82017-07-11 01:36:33 -0500184
Patrick Williams3eedbe42017-05-31 17:27:05 -0500185 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500186}
187
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500188void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
189{
190 auto depth = 0;
191 auto mapperCall = bus.new_method_call(MAPPER_BUSNAME,
192 MAPPER_OBJ_PATH,
193 MAPPER_IFACE,
194 "GetSubTree");
195 mapperCall.append("/");
196 mapperCall.append(depth);
197 mapperCall.append(std::vector<Interface>({LOG_IFACE}));
198
199 auto mapperResponseMsg = bus.call(mapperCall);
200 if (mapperResponseMsg.is_method_error())
201 {
202 using namespace xyz::openbmc_project::Led::Mapper;
203 report<MethodErr>(
204 MethodError::METHOD_NAME("GetSubTree"),
205 MethodError::PATH(MAPPER_OBJ_PATH),
206 MethodError::INTERFACE(
207 OBJMGR_IFACE));
208 return;
209 }
210
211 MapperResponseType mapperResponse;
212 mapperResponseMsg.read(mapperResponse);
213 if (mapperResponse.empty())
214 {
Dhruvaraj Subhashchandranfc30e0c2017-09-19 03:59:08 -0500215 //No errors to process.
Dhruvaraj Subhashchandran891c4762017-07-31 14:26:37 -0500216 return;
217 }
218
219 for (const auto& elem : mapperResponse)
220 {
221 auto method = bus.new_method_call(elem.second.begin()->first.c_str(),
222 elem.first.c_str(),
223 "org.freedesktop.DBus.Properties",
224 "Get");
225 method.append("org.openbmc.Associations");
226 method.append("associations");
227 auto reply = bus.call(method);
228 if (reply.is_method_error())
229 {
230 //do not stop, continue with next elog
231 log<level::ERR>("Error in getting associations");
232 continue;
233 }
234
235 sdbusplus::message::variant<AssociationList> assoc;
236 reply.read(assoc);
237 auto& assocs = assoc.get<AssociationList>();
238 if (assocs.empty())
239 {
240 //no associations, skip
241 continue;
242 }
243
244 for (const auto& item : assocs)
245 {
246 if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
247 {
248 removeWatches.emplace_back(
249 std::make_unique<Remove>(bus, std::get<2>(item)));
250 action(bus, std::get<2>(item), true);
251 }
252 }
253 }
254}
255
Patrick Williams3eedbe42017-05-31 17:27:05 -0500256void Remove::removed(sdbusplus::message::message& msg)
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500257{
Patrick Williams3eedbe42017-05-31 17:27:05 -0500258 auto bus = msg.get_bus();
Dhruvaraj Subhashchandran3c6f29a2017-04-20 09:47:28 -0500259
Patrick Williams3eedbe42017-05-31 17:27:05 -0500260 action(bus, inventoryPath, false);
261 return;
Dhruvaraj Subhashchandran59b86cd2017-04-13 00:19:44 -0500262}
263
264}//namespace monitor
265}//namespace fault
266}//namespace fru
267}//namespace led
268}//namespace phosphor