191ac8d3aSPatrick Venture #include "fru-fault-monitor.hpp"
291ac8d3aSPatrick Venture 
391ac8d3aSPatrick Venture #include "elog-errors.hpp"
43c6f29a0SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Led/Fru/Monitor/error.hpp"
53c6f29a0SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Led/Mapper/error.hpp"
691ac8d3aSPatrick Venture 
791ac8d3aSPatrick Venture #include <phosphor-logging/elog.hpp>
891ac8d3aSPatrick Venture #include <sdbusplus/exception.hpp>
93c6f29a0SDhruvaraj Subhashchandran 
1059b86cd7SDhruvaraj Subhashchandran namespace phosphor
1159b86cd7SDhruvaraj Subhashchandran {
1259b86cd7SDhruvaraj Subhashchandran namespace led
1359b86cd7SDhruvaraj Subhashchandran {
1459b86cd7SDhruvaraj Subhashchandran namespace fru
1559b86cd7SDhruvaraj Subhashchandran {
1659b86cd7SDhruvaraj Subhashchandran namespace fault
1759b86cd7SDhruvaraj Subhashchandran {
1859b86cd7SDhruvaraj Subhashchandran namespace monitor
1959b86cd7SDhruvaraj Subhashchandran {
2059b86cd7SDhruvaraj Subhashchandran 
213c6f29a0SDhruvaraj Subhashchandran using namespace phosphor::logging;
223c6f29a0SDhruvaraj Subhashchandran 
233c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
243c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper";
253c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper";
263c6f29a0SDhruvaraj Subhashchandran constexpr auto OBJMGR_IFACE = "org.freedesktop.DBus.ObjectManager";
273c6f29a0SDhruvaraj Subhashchandran constexpr auto LED_GROUPS = "/xyz/openbmc_project/led/groups/";
283c6f29a0SDhruvaraj Subhashchandran constexpr auto LOG_PATH = "/xyz/openbmc_project/logging";
29891c4769SDhruvaraj Subhashchandran constexpr auto LOG_IFACE = "xyz.openbmc_project.Logging.Entry";
303c6f29a0SDhruvaraj Subhashchandran 
3191ac8d3aSPatrick Venture using AssociationList =
3291ac8d3aSPatrick Venture     std::vector<std::tuple<std::string, std::string, std::string>>;
33aebfde81SDhruvaraj Subhashchandran using Attributes = sdbusplus::message::variant<bool, AssociationList>;
34aebfde81SDhruvaraj Subhashchandran using PropertyName = std::string;
35b2f253b7SMatt Spinler using PropertyMap = std::map<PropertyName, Attributes>;
36b2f253b7SMatt Spinler using InterfaceName = std::string;
37b2f253b7SMatt Spinler using InterfaceMap = std::map<InterfaceName, PropertyMap>;
38aebfde81SDhruvaraj Subhashchandran 
39891c4769SDhruvaraj Subhashchandran using Service = std::string;
40891c4769SDhruvaraj Subhashchandran using Path = std::string;
41891c4769SDhruvaraj Subhashchandran using Interface = std::string;
42891c4769SDhruvaraj Subhashchandran using Interfaces = std::vector<Interface>;
43891c4769SDhruvaraj Subhashchandran using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
44891c4769SDhruvaraj Subhashchandran 
453c6f29a0SDhruvaraj Subhashchandran using MethodErr =
463c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError;
473c6f29a0SDhruvaraj Subhashchandran using ObjectNotFoundErr =
483c6f29a0SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError;
4991ac8d3aSPatrick Venture using InventoryPathErr = sdbusplus::xyz::openbmc_project::Led::Fru::Monitor::
5091ac8d3aSPatrick Venture     Error::InventoryPathError;
513c6f29a0SDhruvaraj Subhashchandran 
5291ac8d3aSPatrick Venture std::string getService(sdbusplus::bus::bus& bus, const std::string& path)
533c6f29a0SDhruvaraj Subhashchandran {
5491ac8d3aSPatrick Venture     auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
553c6f29a0SDhruvaraj Subhashchandran                                       MAPPER_IFACE, "GetObject");
563c6f29a0SDhruvaraj Subhashchandran     mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE}));
573c6f29a0SDhruvaraj Subhashchandran     auto mapperResponseMsg = bus.call(mapper);
583c6f29a0SDhruvaraj Subhashchandran     if (mapperResponseMsg.is_method_error())
593c6f29a0SDhruvaraj Subhashchandran     {
603c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
6191ac8d3aSPatrick Venture         elog<MethodErr>(MethodError::METHOD_NAME("GetObject"),
623c6f29a0SDhruvaraj Subhashchandran                         MethodError::PATH(path.c_str()),
6391ac8d3aSPatrick Venture                         MethodError::INTERFACE(OBJMGR_IFACE));
643c6f29a0SDhruvaraj Subhashchandran     }
653c6f29a0SDhruvaraj Subhashchandran 
663c6f29a0SDhruvaraj Subhashchandran     std::map<std::string, std::vector<std::string>> mapperResponse;
67151122aaSWilliam A. Kennington III     try
68151122aaSWilliam A. Kennington III     {
693c6f29a0SDhruvaraj Subhashchandran         mapperResponseMsg.read(mapperResponse);
70151122aaSWilliam A. Kennington III     }
71151122aaSWilliam A. Kennington III     catch (const sdbusplus::exception::SdBusError& e)
72151122aaSWilliam A. Kennington III     {
7391ac8d3aSPatrick Venture         log<level::ERR>(
7491ac8d3aSPatrick Venture             "Failed to parse getService mapper response",
75151122aaSWilliam A. Kennington III             entry("ERROR=%s", e.what()),
76151122aaSWilliam A. Kennington III             entry("REPLY_SIG=%s", mapperResponseMsg.get_signature()));
77151122aaSWilliam A. Kennington III         using namespace xyz::openbmc_project::Led::Mapper;
7891ac8d3aSPatrick Venture         elog<ObjectNotFoundErr>(ObjectNotFoundError::METHOD_NAME("GetObject"),
79151122aaSWilliam A. Kennington III                                 ObjectNotFoundError::PATH(path.c_str()),
8091ac8d3aSPatrick Venture                                 ObjectNotFoundError::INTERFACE(OBJMGR_IFACE));
81151122aaSWilliam A. Kennington III     }
823c6f29a0SDhruvaraj Subhashchandran     if (mapperResponse.empty())
833c6f29a0SDhruvaraj Subhashchandran     {
843c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Mapper;
8591ac8d3aSPatrick Venture         elog<ObjectNotFoundErr>(ObjectNotFoundError::METHOD_NAME("GetObject"),
863c6f29a0SDhruvaraj Subhashchandran                                 ObjectNotFoundError::PATH(path.c_str()),
8791ac8d3aSPatrick Venture                                 ObjectNotFoundError::INTERFACE(OBJMGR_IFACE));
883c6f29a0SDhruvaraj Subhashchandran     }
893c6f29a0SDhruvaraj Subhashchandran 
903c6f29a0SDhruvaraj Subhashchandran     return mapperResponse.cbegin()->first;
913c6f29a0SDhruvaraj Subhashchandran }
923c6f29a0SDhruvaraj Subhashchandran 
9391ac8d3aSPatrick Venture void action(sdbusplus::bus::bus& bus, const std::string& path, bool assert)
9459b86cd7SDhruvaraj Subhashchandran {
953c6f29a0SDhruvaraj Subhashchandran     std::string service;
963c6f29a0SDhruvaraj Subhashchandran     try
973c6f29a0SDhruvaraj Subhashchandran     {
98e77b8345SMatt Spinler         std::string groups{LED_GROUPS};
99e77b8345SMatt Spinler         groups.pop_back();
100e77b8345SMatt Spinler         service = getService(bus, groups);
1013c6f29a0SDhruvaraj Subhashchandran     }
1023c6f29a0SDhruvaraj Subhashchandran     catch (MethodErr& e)
1033c6f29a0SDhruvaraj Subhashchandran     {
1043c6f29a0SDhruvaraj Subhashchandran         commit<MethodErr>();
1053c6f29a0SDhruvaraj Subhashchandran         return;
1063c6f29a0SDhruvaraj Subhashchandran     }
1073c6f29a0SDhruvaraj Subhashchandran     catch (ObjectNotFoundErr& e)
1083c6f29a0SDhruvaraj Subhashchandran     {
1093c6f29a0SDhruvaraj Subhashchandran         commit<ObjectNotFoundErr>();
1103c6f29a0SDhruvaraj Subhashchandran         return;
1113c6f29a0SDhruvaraj Subhashchandran     }
1123c6f29a0SDhruvaraj Subhashchandran 
1133c6f29a0SDhruvaraj Subhashchandran     auto pos = path.rfind("/");
1143c6f29a0SDhruvaraj Subhashchandran     if (pos == std::string::npos)
1153c6f29a0SDhruvaraj Subhashchandran     {
1163c6f29a0SDhruvaraj Subhashchandran         using namespace xyz::openbmc_project::Led::Fru::Monitor;
11791ac8d3aSPatrick Venture         report<InventoryPathErr>(InventoryPathError::PATH(path.c_str()));
1183c6f29a0SDhruvaraj Subhashchandran         return;
1193c6f29a0SDhruvaraj Subhashchandran     }
1203c6f29a0SDhruvaraj Subhashchandran     auto unit = path.substr(pos + 1);
1213c6f29a0SDhruvaraj Subhashchandran 
12291ac8d3aSPatrick Venture     std::string ledPath = LED_GROUPS + unit + '_' + LED_FAULT;
1233c6f29a0SDhruvaraj Subhashchandran 
12491ac8d3aSPatrick Venture     auto method = bus.new_method_call(service.c_str(), ledPath.c_str(),
12591ac8d3aSPatrick Venture                                       "org.freedesktop.DBus.Properties", "Set");
1263c6f29a0SDhruvaraj Subhashchandran     method.append("xyz.openbmc_project.Led.Group");
1273c6f29a0SDhruvaraj Subhashchandran     method.append("Asserted");
1283c6f29a0SDhruvaraj Subhashchandran 
1293c6f29a0SDhruvaraj Subhashchandran     method.append(sdbusplus::message::variant<bool>(assert));
13008d613e7SAdriana Kobylak 
13108d613e7SAdriana Kobylak     try
13208d613e7SAdriana Kobylak     {
1333c6f29a0SDhruvaraj Subhashchandran         bus.call_noreply(method);
13408d613e7SAdriana Kobylak     }
13508d613e7SAdriana Kobylak     catch (const sdbusplus::exception::SdBusError& e)
13608d613e7SAdriana Kobylak     {
13708d613e7SAdriana Kobylak         // Log an info message, system may not have all the LED Groups defined
13808d613e7SAdriana Kobylak         log<level::INFO>("Failed to Assert LED Group",
13908d613e7SAdriana Kobylak                          entry("ERROR=%s", e.what()));
14008d613e7SAdriana Kobylak     }
1413c6f29a0SDhruvaraj Subhashchandran 
14259b86cd7SDhruvaraj Subhashchandran     return;
14359b86cd7SDhruvaraj Subhashchandran }
14459b86cd7SDhruvaraj Subhashchandran 
1453eedbe44SPatrick Williams void Add::created(sdbusplus::message::message& msg)
14659b86cd7SDhruvaraj Subhashchandran {
1473eedbe44SPatrick Williams     auto bus = msg.get_bus();
1483c6f29a0SDhruvaraj Subhashchandran 
149b2f253b7SMatt Spinler     sdbusplus::message::object_path objectPath;
150b2f253b7SMatt Spinler     InterfaceMap interfaces;
151151122aaSWilliam A. Kennington III     try
152151122aaSWilliam A. Kennington III     {
153b2f253b7SMatt Spinler         msg.read(objectPath, interfaces);
154151122aaSWilliam A. Kennington III     }
155151122aaSWilliam A. Kennington III     catch (const sdbusplus::exception::SdBusError& e)
156151122aaSWilliam A. Kennington III     {
157151122aaSWilliam A. Kennington III         log<level::ERR>("Failed to parse created message",
158151122aaSWilliam A. Kennington III                         entry("ERROR=%s", e.what()),
159151122aaSWilliam A. Kennington III                         entry("REPLY_SIG=%s", msg.get_signature()));
160151122aaSWilliam A. Kennington III         return;
161151122aaSWilliam A. Kennington III     }
1623c6f29a0SDhruvaraj Subhashchandran 
163b2f253b7SMatt Spinler     std::size_t found = objectPath.str.find(ELOG_ENTRY);
1643c6f29a0SDhruvaraj Subhashchandran     if (found == std::string::npos)
1653c6f29a0SDhruvaraj Subhashchandran     {
1663c6f29a0SDhruvaraj Subhashchandran         // Not a new error entry skip
1673eedbe44SPatrick Williams         return;
1683c6f29a0SDhruvaraj Subhashchandran     }
169*a6e48929SAndrew Geissler     auto iter = interfaces.find("xyz.openbmc_project.Association.Definitions");
170b2f253b7SMatt Spinler     if (iter == interfaces.end())
1713c6f29a0SDhruvaraj Subhashchandran     {
1723eedbe44SPatrick Williams         return;
1733c6f29a0SDhruvaraj Subhashchandran     }
1743c6f29a0SDhruvaraj Subhashchandran 
1753d2b0d62SMatt Spinler     // Nothing else shows when a specific error log
1763d2b0d62SMatt Spinler     // has been created. Do it here.
177b2f253b7SMatt Spinler     std::string message{objectPath.str + " created"};
1783d2b0d62SMatt Spinler     log<level::INFO>(message.c_str());
1793d2b0d62SMatt Spinler 
180*a6e48929SAndrew Geissler     auto attr = iter->second.find("Associations");
181aebfde81SDhruvaraj Subhashchandran     if (attr == iter->second.end())
1823c6f29a0SDhruvaraj Subhashchandran     {
1833eedbe44SPatrick Williams         return;
1843c6f29a0SDhruvaraj Subhashchandran     }
1853c6f29a0SDhruvaraj Subhashchandran 
186aebfde81SDhruvaraj Subhashchandran     auto& assocs =
187aebfde81SDhruvaraj Subhashchandran         sdbusplus::message::variant_ns::get<AssociationList>(attr->second);
1883c6f29a0SDhruvaraj Subhashchandran     if (assocs.empty())
1893c6f29a0SDhruvaraj Subhashchandran     {
1903c6f29a0SDhruvaraj Subhashchandran         // No associations skip
1913eedbe44SPatrick Williams         return;
1923c6f29a0SDhruvaraj Subhashchandran     }
1933c6f29a0SDhruvaraj Subhashchandran 
1943c6f29a0SDhruvaraj Subhashchandran     for (const auto& item : assocs)
1953c6f29a0SDhruvaraj Subhashchandran     {
1963c6f29a0SDhruvaraj Subhashchandran         if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
1973c6f29a0SDhruvaraj Subhashchandran         {
1983eedbe44SPatrick Williams             removeWatches.emplace_back(
1993c6f29a0SDhruvaraj Subhashchandran                 std::make_unique<Remove>(bus, std::get<2>(item)));
200891c4769SDhruvaraj Subhashchandran             action(bus, std::get<2>(item), true);
2013c6f29a0SDhruvaraj Subhashchandran         }
2023c6f29a0SDhruvaraj Subhashchandran     }
203aebfde81SDhruvaraj Subhashchandran 
2043eedbe44SPatrick Williams     return;
20559b86cd7SDhruvaraj Subhashchandran }
20659b86cd7SDhruvaraj Subhashchandran 
20791122927SMatt Spinler void getLoggingSubTree(sdbusplus::bus::bus& bus, MapperResponseType& subtree)
208891c4769SDhruvaraj Subhashchandran {
209891c4769SDhruvaraj Subhashchandran     auto depth = 0;
21091ac8d3aSPatrick Venture     auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_OBJ_PATH,
21191ac8d3aSPatrick Venture                                           MAPPER_IFACE, "GetSubTree");
212891c4769SDhruvaraj Subhashchandran     mapperCall.append("/");
213891c4769SDhruvaraj Subhashchandran     mapperCall.append(depth);
214891c4769SDhruvaraj Subhashchandran     mapperCall.append(std::vector<Interface>({LOG_IFACE}));
215891c4769SDhruvaraj Subhashchandran 
21691122927SMatt Spinler     try
21791122927SMatt Spinler     {
218891c4769SDhruvaraj Subhashchandran         auto mapperResponseMsg = bus.call(mapperCall);
219891c4769SDhruvaraj Subhashchandran         if (mapperResponseMsg.is_method_error())
220891c4769SDhruvaraj Subhashchandran         {
221891c4769SDhruvaraj Subhashchandran             using namespace xyz::openbmc_project::Led::Mapper;
22291ac8d3aSPatrick Venture             report<MethodErr>(MethodError::METHOD_NAME("GetSubTree"),
223891c4769SDhruvaraj Subhashchandran                               MethodError::PATH(MAPPER_OBJ_PATH),
22491122927SMatt Spinler                               MethodError::INTERFACE(OBJMGR_IFACE));
225891c4769SDhruvaraj Subhashchandran             return;
226891c4769SDhruvaraj Subhashchandran         }
227891c4769SDhruvaraj Subhashchandran 
228151122aaSWilliam A. Kennington III         try
229151122aaSWilliam A. Kennington III         {
23091122927SMatt Spinler             mapperResponseMsg.read(subtree);
231151122aaSWilliam A. Kennington III         }
232151122aaSWilliam A. Kennington III         catch (const sdbusplus::exception::SdBusError& e)
233151122aaSWilliam A. Kennington III         {
23491ac8d3aSPatrick Venture             log<level::ERR>(
23591ac8d3aSPatrick Venture                 "Failed to parse existing callouts subtree message",
236151122aaSWilliam A. Kennington III                 entry("ERROR=%s", e.what()),
237151122aaSWilliam A. Kennington III                 entry("REPLY_SIG=%s", mapperResponseMsg.get_signature()));
238151122aaSWilliam A. Kennington III         }
23991122927SMatt Spinler     }
24091122927SMatt Spinler     catch (const sdbusplus::exception::SdBusError& e)
24191122927SMatt Spinler     {
24291122927SMatt Spinler         // Just means no log entries at the moment
24391122927SMatt Spinler     }
24491122927SMatt Spinler }
24591122927SMatt Spinler 
24691122927SMatt Spinler void Add::processExistingCallouts(sdbusplus::bus::bus& bus)
24791122927SMatt Spinler {
24891122927SMatt Spinler     MapperResponseType mapperResponse;
24991122927SMatt Spinler 
25091122927SMatt Spinler     getLoggingSubTree(bus, mapperResponse);
251891c4769SDhruvaraj Subhashchandran     if (mapperResponse.empty())
252891c4769SDhruvaraj Subhashchandran     {
253fc30e0c1SDhruvaraj Subhashchandran         // No errors to process.
254891c4769SDhruvaraj Subhashchandran         return;
255891c4769SDhruvaraj Subhashchandran     }
256891c4769SDhruvaraj Subhashchandran 
257891c4769SDhruvaraj Subhashchandran     for (const auto& elem : mapperResponse)
258891c4769SDhruvaraj Subhashchandran     {
25991ac8d3aSPatrick Venture         auto method = bus.new_method_call(
26091ac8d3aSPatrick Venture             elem.second.begin()->first.c_str(), elem.first.c_str(),
26191ac8d3aSPatrick Venture             "org.freedesktop.DBus.Properties", "Get");
262*a6e48929SAndrew Geissler         method.append("xyz.openbmc_project.Association.Definitions");
263*a6e48929SAndrew Geissler         method.append("Associations");
264891c4769SDhruvaraj Subhashchandran         auto reply = bus.call(method);
265891c4769SDhruvaraj Subhashchandran         if (reply.is_method_error())
266891c4769SDhruvaraj Subhashchandran         {
267891c4769SDhruvaraj Subhashchandran             // do not stop, continue with next elog
268891c4769SDhruvaraj Subhashchandran             log<level::ERR>("Error in getting associations");
269891c4769SDhruvaraj Subhashchandran             continue;
270891c4769SDhruvaraj Subhashchandran         }
271891c4769SDhruvaraj Subhashchandran 
272891c4769SDhruvaraj Subhashchandran         sdbusplus::message::variant<AssociationList> assoc;
273151122aaSWilliam A. Kennington III         try
274151122aaSWilliam A. Kennington III         {
275891c4769SDhruvaraj Subhashchandran             reply.read(assoc);
276151122aaSWilliam A. Kennington III         }
277151122aaSWilliam A. Kennington III         catch (const sdbusplus::exception::SdBusError& e)
278151122aaSWilliam A. Kennington III         {
27991ac8d3aSPatrick Venture             log<level::ERR>(
28091ac8d3aSPatrick Venture                 "Failed to parse existing callouts associations message",
281151122aaSWilliam A. Kennington III                 entry("ERROR=%s", e.what()),
282151122aaSWilliam A. Kennington III                 entry("REPLY_SIG=%s", reply.get_signature()));
283151122aaSWilliam A. Kennington III             continue;
284151122aaSWilliam A. Kennington III         }
285555a279eSWilliam A. Kennington III         auto& assocs =
286555a279eSWilliam A. Kennington III             sdbusplus::message::variant_ns::get<AssociationList>(assoc);
287891c4769SDhruvaraj Subhashchandran         if (assocs.empty())
288891c4769SDhruvaraj Subhashchandran         {
289891c4769SDhruvaraj Subhashchandran             // no associations, skip
290891c4769SDhruvaraj Subhashchandran             continue;
291891c4769SDhruvaraj Subhashchandran         }
292891c4769SDhruvaraj Subhashchandran 
293891c4769SDhruvaraj Subhashchandran         for (const auto& item : assocs)
294891c4769SDhruvaraj Subhashchandran         {
295891c4769SDhruvaraj Subhashchandran             if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0)
296891c4769SDhruvaraj Subhashchandran             {
297891c4769SDhruvaraj Subhashchandran                 removeWatches.emplace_back(
298891c4769SDhruvaraj Subhashchandran                     std::make_unique<Remove>(bus, std::get<2>(item)));
299891c4769SDhruvaraj Subhashchandran                 action(bus, std::get<2>(item), true);
300891c4769SDhruvaraj Subhashchandran             }
301891c4769SDhruvaraj Subhashchandran         }
302891c4769SDhruvaraj Subhashchandran     }
303891c4769SDhruvaraj Subhashchandran }
304891c4769SDhruvaraj Subhashchandran 
3053eedbe44SPatrick Williams void Remove::removed(sdbusplus::message::message& msg)
30659b86cd7SDhruvaraj Subhashchandran {
3073eedbe44SPatrick Williams     auto bus = msg.get_bus();
3083c6f29a0SDhruvaraj Subhashchandran 
3093eedbe44SPatrick Williams     action(bus, inventoryPath, false);
3103eedbe44SPatrick Williams     return;
31159b86cd7SDhruvaraj Subhashchandran }
31259b86cd7SDhruvaraj Subhashchandran 
31359b86cd7SDhruvaraj Subhashchandran } // namespace monitor
31459b86cd7SDhruvaraj Subhashchandran } // namespace fault
31559b86cd7SDhruvaraj Subhashchandran } // namespace fru
31659b86cd7SDhruvaraj Subhashchandran } // namespace led
31759b86cd7SDhruvaraj Subhashchandran } // namespace phosphor
318