xref: /openbmc/phosphor-led-manager/fault-monitor/fru-fault-monitor.cpp (revision 891c4769f19d0505894a816aeca66be2113d708e)
13c6f29a0SDhruvaraj Subhashchandran #include <phosphor-logging/elog.hpp>
23c6f29a0SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Led/Fru/Monitor/error.hpp"
33c6f29a0SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Led/Mapper/error.hpp"
43c6f29a0SDhruvaraj Subhashchandran #include "elog-errors.hpp"
559b86cd7SDhruvaraj Subhashchandran #include "fru-fault-monitor.hpp"
6*891c4769SDhruvaraj Subhashchandran #include <phosphor-logging/elog-errors.hpp>
7*891c4769SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Common/error.hpp"
83c6f29a0SDhruvaraj Subhashchandran 
959b86cd7SDhruvaraj Subhashchandran namespace phosphor
1059b86cd7SDhruvaraj Subhashchandran {
1159b86cd7SDhruvaraj Subhashchandran namespace led
1259b86cd7SDhruvaraj Subhashchandran {
1359b86cd7SDhruvaraj Subhashchandran namespace fru
1459b86cd7SDhruvaraj Subhashchandran {
1559b86cd7SDhruvaraj Subhashchandran namespace fault
1659b86cd7SDhruvaraj Subhashchandran {
1759b86cd7SDhruvaraj Subhashchandran namespace monitor
1859b86cd7SDhruvaraj Subhashchandran {
1959b86cd7SDhruvaraj Subhashchandran 
203c6f29a0SDhruvaraj Subhashchandran using namespace phosphor::logging;
213c6f29a0SDhruvaraj Subhashchandran 
223c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_BUSNAME   = "xyz.openbmc_project.ObjectMapper";
233c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_OBJ_PATH  = "/xyz/openbmc_project/object_mapper";
243c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_IFACE     = "xyz.openbmc_project.ObjectMapper";
253c6f29a0SDhruvaraj Subhashchandran constexpr auto OBJMGR_IFACE     = "org.freedesktop.DBus.ObjectManager";
263c6f29a0SDhruvaraj Subhashchandran constexpr auto LED_GROUPS       = "/xyz/openbmc_project/led/groups/";
273c6f29a0SDhruvaraj Subhashchandran constexpr auto LOG_PATH         = "/xyz/openbmc_project/logging";
28*891c4769SDhruvaraj Subhashchandran constexpr auto LOG_IFACE        = "xyz.openbmc_project.Logging.Entry";
293c6f29a0SDhruvaraj Subhashchandran 
303c6f29a0SDhruvaraj Subhashchandran using AssociationList = std::vector<std::tuple<
313c6f29a0SDhruvaraj Subhashchandran                         std::string, std::string, std::string>>;
32aebfde81SDhruvaraj Subhashchandran using Attributes = sdbusplus::message::variant<bool,AssociationList>;
33aebfde81SDhruvaraj Subhashchandran using AttributeName = std::string;
34aebfde81SDhruvaraj Subhashchandran using AttributeMap = std::map<AttributeName, Attributes>;
35aebfde81SDhruvaraj Subhashchandran using PropertyName = std::string;
36aebfde81SDhruvaraj Subhashchandran using PropertyMap = std::map<PropertyName, AttributeMap>;
37aebfde81SDhruvaraj Subhashchandran using LogEntryMsg = std::pair<sdbusplus::message::object_path, PropertyMap>;
38aebfde81SDhruvaraj Subhashchandran 
39*891c4769SDhruvaraj Subhashchandran using Service = std::string;
40*891c4769SDhruvaraj Subhashchandran using Path = std::string;
41*891c4769SDhruvaraj Subhashchandran using Interface = std::string;
42*891c4769SDhruvaraj Subhashchandran using Interfaces = std::vector<Interface>;
43*891c4769SDhruvaraj Subhashchandran using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
44*891c4769SDhruvaraj Subhashchandran 
45*891c4769SDhruvaraj Subhashchandran using InternalFailure =
46*891c4769SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
47*891c4769SDhruvaraj Subhashchandran 
483c6f29a0SDhruvaraj Subhashchandran using MethodErr  =
493c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
503c6f29a0SDhruvaraj Subhashchandran using ObjectNotFoundErr =
513c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
523c6f29a0SDhruvaraj Subhashchandran using InventoryPathErr =
533c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::
543c6f29a0SDhruvaraj Subhashchandran     Led::Fru::Monitor::Error::InventoryPathError;
553c6f29a0SDhruvaraj Subhashchandran 
563c6f29a0SDhruvaraj Subhashchandran std::string getService(sdbusplus::bus::bus& bus,
573c6f29a0SDhruvaraj Subhashchandran                        const std::string& path)
583c6f29a0SDhruvaraj Subhashchandran {
593c6f29a0SDhruvaraj Subhashchandran     auto mapper = bus.new_method_call(MAPPER_BUSNAME,
603c6f29a0SDhruvaraj Subhashchandran                                       MAPPER_OBJ_PATH,
613c6f29a0SDhruvaraj Subhashchandran                                       MAPPER_IFACE, "GetObject");
623c6f29a0SDhruvaraj Subhashchandran     mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
633c6f29a0SDhruvaraj Subhashchandran     auto mapperResponseMsg = bus.call(mapper);
643c6f29a0SDhruvaraj Subhashchandran     if (mapperResponseMsg.is_method_error())
653c6f29a0SDhruvaraj Subhashchandran     {
663c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
673c6f29a0SDhruvaraj Subhashchandran         elog<MethodErr>(
683c6f29a0SDhruvaraj Subhashchandran             MethodError::METHOD_NAME("GetObject"),
693c6f29a0SDhruvaraj Subhashchandran             MethodError::PATH(path.c_str()),
703c6f29a0SDhruvaraj Subhashchandran             MethodError::INTERFACE(
713c6f29a0SDhruvaraj Subhashchandran                 OBJMGR_IFACE));
723c6f29a0SDhruvaraj Subhashchandran     }
733c6f29a0SDhruvaraj Subhashchandran 
743c6f29a0SDhruvaraj Subhashchandran     std::map<std::string, std::vector<std::string>> mapperResponse;
753c6f29a0SDhruvaraj Subhashchandran     mapperResponseMsg.read(mapperResponse);
763c6f29a0SDhruvaraj Subhashchandran     if (mapperResponse.empty())
773c6f29a0SDhruvaraj Subhashchandran     {
783c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
793c6f29a0SDhruvaraj Subhashchandran         elog<ObjectNotFoundErr>(
803c6f29a0SDhruvaraj Subhashchandran             ObjectNotFoundError::METHOD_NAME("GetObject"),
813c6f29a0SDhruvaraj Subhashchandran             ObjectNotFoundError::PATH(path.c_str()),
823c6f29a0SDhruvaraj Subhashchandran             ObjectNotFoundError::INTERFACE(
833c6f29a0SDhruvaraj Subhashchandran                 OBJMGR_IFACE));
843c6f29a0SDhruvaraj Subhashchandran     }
853c6f29a0SDhruvaraj Subhashchandran 
863c6f29a0SDhruvaraj Subhashchandran     return mapperResponse.cbegin()->first;
873c6f29a0SDhruvaraj Subhashchandran }
883c6f29a0SDhruvaraj Subhashchandran 
8959b86cd7SDhruvaraj Subhashchandran void action(sdbusplus::bus::bus& bus,
903c6f29a0SDhruvaraj Subhashchandran             const std::string& path,
9159b86cd7SDhruvaraj Subhashchandran             bool assert)
9259b86cd7SDhruvaraj Subhashchandran {
933c6f29a0SDhruvaraj Subhashchandran     std::string service;
943c6f29a0SDhruvaraj Subhashchandran     try
953c6f29a0SDhruvaraj Subhashchandran     {
963c6f29a0SDhruvaraj Subhashchandran         service = getService(bus, LED_GROUPS);
973c6f29a0SDhruvaraj Subhashchandran     }
983c6f29a0SDhruvaraj Subhashchandran     catch (MethodErr& e)
993c6f29a0SDhruvaraj Subhashchandran     {
1003c6f29a0SDhruvaraj Subhashchandran         commit<MethodErr>();
1013c6f29a0SDhruvaraj Subhashchandran         return;
1023c6f29a0SDhruvaraj Subhashchandran     }
1033c6f29a0SDhruvaraj Subhashchandran     catch (ObjectNotFoundErr& e)
1043c6f29a0SDhruvaraj Subhashchandran     {
1053c6f29a0SDhruvaraj Subhashchandran         commit<ObjectNotFoundErr>();
1063c6f29a0SDhruvaraj Subhashchandran         return;
1073c6f29a0SDhruvaraj Subhashchandran     }
1083c6f29a0SDhruvaraj Subhashchandran 
1093c6f29a0SDhruvaraj Subhashchandran     auto pos = path.rfind("/");
1103c6f29a0SDhruvaraj Subhashchandran     if (pos == std::string::npos)
1113c6f29a0SDhruvaraj Subhashchandran     {
1123c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Fru::Monitor;
1133c6f29a0SDhruvaraj Subhashchandran         report<InventoryPathErr>(
1143c6f29a0SDhruvaraj Subhashchandran             InventoryPathError::PATH(
1153c6f29a0SDhruvaraj Subhashchandran                 path.c_str()));
1163c6f29a0SDhruvaraj Subhashchandran         return;
1173c6f29a0SDhruvaraj Subhashchandran     }
1183c6f29a0SDhruvaraj Subhashchandran     auto unit = path.substr(pos + 1);
1193c6f29a0SDhruvaraj Subhashchandran 
1203c6f29a0SDhruvaraj Subhashchandran     std::string ledPath = LED_GROUPS +
1213c6f29a0SDhruvaraj Subhashchandran                           unit + '_' + LED_FAULT;
1223c6f29a0SDhruvaraj Subhashchandran 
1233c6f29a0SDhruvaraj Subhashchandran     auto method =  bus.new_method_call(service.c_str(),
1243c6f29a0SDhruvaraj Subhashchandran                                        ledPath.c_str(),
1253c6f29a0SDhruvaraj Subhashchandran                                        "org.freedesktop.DBus.Properties",
1263c6f29a0SDhruvaraj Subhashchandran                                        "Set");
1273c6f29a0SDhruvaraj Subhashchandran     method.append("xyz.openbmc_project.Led.Group");
1283c6f29a0SDhruvaraj Subhashchandran     method.append("Asserted");
1293c6f29a0SDhruvaraj Subhashchandran 
1303c6f29a0SDhruvaraj Subhashchandran     method.append(sdbusplus::message::variant<bool>(assert));
1313c6f29a0SDhruvaraj Subhashchandran     bus.call_noreply(method);
1323c6f29a0SDhruvaraj Subhashchandran 
13359b86cd7SDhruvaraj Subhashchandran     return;
13459b86cd7SDhruvaraj Subhashchandran }
13559b86cd7SDhruvaraj Subhashchandran 
1363eedbe44SPatrick Williams void Add::created(sdbusplus::message::message& msg)
13759b86cd7SDhruvaraj Subhashchandran {
1383eedbe44SPatrick Williams     auto bus = msg.get_bus();
1393c6f29a0SDhruvaraj Subhashchandran 
140aebfde81SDhruvaraj Subhashchandran     LogEntryMsg logEntry;
141aebfde81SDhruvaraj Subhashchandran     msg.read(logEntry);
142aebfde81SDhruvaraj Subhashchandran     std::string objectPath(std::move(logEntry.first));
1433c6f29a0SDhruvaraj Subhashchandran 
1443c6f29a0SDhruvaraj Subhashchandran     std::size_t found = objectPath.find(ELOG_ENTRY);
1453c6f29a0SDhruvaraj Subhashchandran     if (found == std::string::npos)
1463c6f29a0SDhruvaraj Subhashchandran     {
1473c6f29a0SDhruvaraj Subhashchandran         //Not a new error entry skip
1483eedbe44SPatrick Williams         return;
1493c6f29a0SDhruvaraj Subhashchandran     }
150aebfde81SDhruvaraj Subhashchandran     log<level::ERR>(objectPath.c_str());
1513c6f29a0SDhruvaraj Subhashchandran 
152aebfde81SDhruvaraj Subhashchandran     auto iter = logEntry.second.find("org.openbmc.Associations");
153aebfde81SDhruvaraj Subhashchandran     if (iter == logEntry.second.end())
1543c6f29a0SDhruvaraj Subhashchandran     {
1553eedbe44SPatrick Williams         return;
1563c6f29a0SDhruvaraj Subhashchandran     }
1573c6f29a0SDhruvaraj Subhashchandran 
158aebfde81SDhruvaraj Subhashchandran     auto attr = iter->second.find("associations");
159aebfde81SDhruvaraj Subhashchandran     if (attr == iter->second.end())
1603c6f29a0SDhruvaraj Subhashchandran     {
1613eedbe44SPatrick Williams         return;
1623c6f29a0SDhruvaraj Subhashchandran     }
1633c6f29a0SDhruvaraj Subhashchandran 
164aebfde81SDhruvaraj Subhashchandran     auto& assocs =
165aebfde81SDhruvaraj Subhashchandran         sdbusplus::message::variant_ns::get<AssociationList>(attr->second);
1663c6f29a0SDhruvaraj Subhashchandran     if (assocs.empty())
1673c6f29a0SDhruvaraj Subhashchandran     {
1683c6f29a0SDhruvaraj Subhashchandran         //No associations skip
1693eedbe44SPatrick Williams         return;
1703c6f29a0SDhruvaraj Subhashchandran     }
1713c6f29a0SDhruvaraj Subhashchandran 
1723c6f29a0SDhruvaraj Subhashchandran     for (const auto& item : assocs)
1733c6f29a0SDhruvaraj Subhashchandran     {
1743c6f29a0SDhruvaraj Subhashchandran         if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
1753c6f29a0SDhruvaraj Subhashchandran         {
1763eedbe44SPatrick Williams             removeWatches.emplace_back(
1773c6f29a0SDhruvaraj Subhashchandran                 std::make_unique<Remove>(bus, std::get<2>(item)));
178*891c4769SDhruvaraj Subhashchandran             action(bus, std::get<2>(item), true);
1793c6f29a0SDhruvaraj Subhashchandran         }
1803c6f29a0SDhruvaraj Subhashchandran     }
181aebfde81SDhruvaraj Subhashchandran 
1823eedbe44SPatrick Williams     return;
18359b86cd7SDhruvaraj Subhashchandran }
18459b86cd7SDhruvaraj Subhashchandran 
185*891c4769SDhruvaraj Subhashchandran void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
186*891c4769SDhruvaraj Subhashchandran {
187*891c4769SDhruvaraj Subhashchandran     auto depth = 0;
188*891c4769SDhruvaraj Subhashchandran     auto mapperCall = bus.new_method_call(MAPPER_BUSNAME,
189*891c4769SDhruvaraj Subhashchandran                                           MAPPER_OBJ_PATH,
190*891c4769SDhruvaraj Subhashchandran                                           MAPPER_IFACE,
191*891c4769SDhruvaraj Subhashchandran                                           "GetSubTree");
192*891c4769SDhruvaraj Subhashchandran     mapperCall.append("/");
193*891c4769SDhruvaraj Subhashchandran     mapperCall.append(depth);
194*891c4769SDhruvaraj Subhashchandran     mapperCall.append(std::vector<Interface>({LOG_IFACE}));
195*891c4769SDhruvaraj Subhashchandran 
196*891c4769SDhruvaraj Subhashchandran     auto mapperResponseMsg = bus.call(mapperCall);
197*891c4769SDhruvaraj Subhashchandran     if (mapperResponseMsg.is_method_error())
198*891c4769SDhruvaraj Subhashchandran     {
199*891c4769SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
200*891c4769SDhruvaraj Subhashchandran         report<MethodErr>(
201*891c4769SDhruvaraj Subhashchandran             MethodError::METHOD_NAME("GetSubTree"),
202*891c4769SDhruvaraj Subhashchandran             MethodError::PATH(MAPPER_OBJ_PATH),
203*891c4769SDhruvaraj Subhashchandran             MethodError::INTERFACE(
204*891c4769SDhruvaraj Subhashchandran                 OBJMGR_IFACE));
205*891c4769SDhruvaraj Subhashchandran         return;
206*891c4769SDhruvaraj Subhashchandran     }
207*891c4769SDhruvaraj Subhashchandran 
208*891c4769SDhruvaraj Subhashchandran     MapperResponseType mapperResponse;
209*891c4769SDhruvaraj Subhashchandran     mapperResponseMsg.read(mapperResponse);
210*891c4769SDhruvaraj Subhashchandran     if (mapperResponse.empty())
211*891c4769SDhruvaraj Subhashchandran     {
212*891c4769SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
213*891c4769SDhruvaraj Subhashchandran         report<ObjectNotFoundErr>(
214*891c4769SDhruvaraj Subhashchandran             ObjectNotFoundError::METHOD_NAME("GetSubTree"),
215*891c4769SDhruvaraj Subhashchandran             ObjectNotFoundError::PATH(MAPPER_OBJ_PATH),
216*891c4769SDhruvaraj Subhashchandran             ObjectNotFoundError::INTERFACE(
217*891c4769SDhruvaraj Subhashchandran                 OBJMGR_IFACE));
218*891c4769SDhruvaraj Subhashchandran         return;
219*891c4769SDhruvaraj Subhashchandran     }
220*891c4769SDhruvaraj Subhashchandran 
221*891c4769SDhruvaraj Subhashchandran     for (const auto& elem : mapperResponse)
222*891c4769SDhruvaraj Subhashchandran     {
223*891c4769SDhruvaraj Subhashchandran         auto method =  bus.new_method_call(elem.second.begin()->first.c_str(),
224*891c4769SDhruvaraj Subhashchandran                                            elem.first.c_str(),
225*891c4769SDhruvaraj Subhashchandran                                            "org.freedesktop.DBus.Properties",
226*891c4769SDhruvaraj Subhashchandran                                            "Get");
227*891c4769SDhruvaraj Subhashchandran         method.append("org.openbmc.Associations");
228*891c4769SDhruvaraj Subhashchandran         method.append("associations");
229*891c4769SDhruvaraj Subhashchandran         auto reply = bus.call(method);
230*891c4769SDhruvaraj Subhashchandran         if (reply.is_method_error())
231*891c4769SDhruvaraj Subhashchandran         {
232*891c4769SDhruvaraj Subhashchandran             //do not stop, continue with next elog
233*891c4769SDhruvaraj Subhashchandran             log<level::ERR>("Error in getting associations");
234*891c4769SDhruvaraj Subhashchandran             continue;
235*891c4769SDhruvaraj Subhashchandran         }
236*891c4769SDhruvaraj Subhashchandran 
237*891c4769SDhruvaraj Subhashchandran         sdbusplus::message::variant<AssociationList> assoc;
238*891c4769SDhruvaraj Subhashchandran         reply.read(assoc);
239*891c4769SDhruvaraj Subhashchandran         auto& assocs = assoc.get<AssociationList>();
240*891c4769SDhruvaraj Subhashchandran         if (assocs.empty())
241*891c4769SDhruvaraj Subhashchandran         {
242*891c4769SDhruvaraj Subhashchandran             //no associations, skip
243*891c4769SDhruvaraj Subhashchandran             continue;
244*891c4769SDhruvaraj Subhashchandran         }
245*891c4769SDhruvaraj Subhashchandran 
246*891c4769SDhruvaraj Subhashchandran         for (const auto& item : assocs)
247*891c4769SDhruvaraj Subhashchandran         {
248*891c4769SDhruvaraj Subhashchandran             if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
249*891c4769SDhruvaraj Subhashchandran             {
250*891c4769SDhruvaraj Subhashchandran                 removeWatches.emplace_back(
251*891c4769SDhruvaraj Subhashchandran                     std::make_unique<Remove>(bus, std::get<2>(item)));
252*891c4769SDhruvaraj Subhashchandran                 action(bus, std::get<2>(item), true);
253*891c4769SDhruvaraj Subhashchandran             }
254*891c4769SDhruvaraj Subhashchandran         }
255*891c4769SDhruvaraj Subhashchandran     }
256*891c4769SDhruvaraj Subhashchandran }
257*891c4769SDhruvaraj Subhashchandran 
2583eedbe44SPatrick Williams void Remove::removed(sdbusplus::message::message& msg)
25959b86cd7SDhruvaraj Subhashchandran {
2603eedbe44SPatrick Williams     auto bus = msg.get_bus();
2613c6f29a0SDhruvaraj Subhashchandran     std::string assoc;
2623eedbe44SPatrick Williams     msg.read(assoc);
2633c6f29a0SDhruvaraj Subhashchandran 
2643c6f29a0SDhruvaraj Subhashchandran     if (assoc.compare("org.openbmc.Association"))
2653c6f29a0SDhruvaraj Subhashchandran     {
2663c6f29a0SDhruvaraj Subhashchandran         //Skip if not about association
2673eedbe44SPatrick Williams         return;
2683c6f29a0SDhruvaraj Subhashchandran     }
2693c6f29a0SDhruvaraj Subhashchandran 
2703c6f29a0SDhruvaraj Subhashchandran     std::map<std::string, std::vector<std::string>> endPoints;
2713eedbe44SPatrick Williams     msg.read(endPoints);
2723c6f29a0SDhruvaraj Subhashchandran     auto it = endPoints.find("endpoints");
2733c6f29a0SDhruvaraj Subhashchandran 
2743c6f29a0SDhruvaraj Subhashchandran     if (it == endPoints.end())
2753c6f29a0SDhruvaraj Subhashchandran     {
2763c6f29a0SDhruvaraj Subhashchandran         //No end points,skip
2773eedbe44SPatrick Williams         return;
2783c6f29a0SDhruvaraj Subhashchandran     }
2793c6f29a0SDhruvaraj Subhashchandran 
2803c6f29a0SDhruvaraj Subhashchandran     if (!((*it).second.empty()))
2813c6f29a0SDhruvaraj Subhashchandran     {
2823c6f29a0SDhruvaraj Subhashchandran         //Skip, end points are not empty
2833eedbe44SPatrick Williams         return;
2843c6f29a0SDhruvaraj Subhashchandran     }
2853c6f29a0SDhruvaraj Subhashchandran 
2863eedbe44SPatrick Williams     action(bus, inventoryPath, false);
2873eedbe44SPatrick Williams     return;
28859b86cd7SDhruvaraj Subhashchandran }
28959b86cd7SDhruvaraj Subhashchandran 
29059b86cd7SDhruvaraj Subhashchandran }//namespace monitor
29159b86cd7SDhruvaraj Subhashchandran }//namespace fault
29259b86cd7SDhruvaraj Subhashchandran }//namespace fru
29359b86cd7SDhruvaraj Subhashchandran }//namespace led
29459b86cd7SDhruvaraj Subhashchandran }//namespace phosphor
295