191ac8d3aSPatrick Venture #include "fru-fault-monitor.hpp" 291ac8d3aSPatrick Venture 39bd334ffSPatrick Williams #include <phosphor-logging/elog-errors.hpp> 491ac8d3aSPatrick Venture #include <phosphor-logging/elog.hpp> 5e9fb5c6aSGeorge Liu #include <phosphor-logging/lg2.hpp> 691ac8d3aSPatrick Venture #include <sdbusplus/exception.hpp> 79bd334ffSPatrick Williams #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 221f0b715aSGeorge Liu static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper"; 231f0b715aSGeorge Liu static constexpr auto mapperObjPath = "/xyz/openbmc_project/object_mapper"; 241f0b715aSGeorge Liu static constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper"; 251f0b715aSGeorge Liu static constexpr auto objMgrIntf = "org.freedesktop.DBus.ObjectManager"; 261f0b715aSGeorge Liu static constexpr auto ledGroups = "/xyz/openbmc_project/led/groups/"; 271f0b715aSGeorge Liu static constexpr auto logIntf = "xyz.openbmc_project.Logging.Entry"; 283c6f29a0SDhruvaraj Subhashchandran 2991ac8d3aSPatrick Venture using AssociationList = 3091ac8d3aSPatrick Venture std::vector<std::tuple<std::string, std::string, std::string>>; 31a41d282aSPatrick Williams using Attributes = std::variant<bool, AssociationList>; 32aebfde81SDhruvaraj Subhashchandran using PropertyName = std::string; 33f2044037SPatrick Williams using PropertyMap = std::unordered_map<PropertyName, Attributes>; 34b2f253b7SMatt Spinler using InterfaceName = std::string; 35f2044037SPatrick Williams using InterfaceMap = std::unordered_map<InterfaceName, PropertyMap>; 36aebfde81SDhruvaraj Subhashchandran 37891c4769SDhruvaraj Subhashchandran using Service = std::string; 38891c4769SDhruvaraj Subhashchandran using Path = std::string; 39891c4769SDhruvaraj Subhashchandran using Interface = std::string; 40891c4769SDhruvaraj Subhashchandran using Interfaces = std::vector<Interface>; 41f2044037SPatrick Williams using MapperResponseType = 42f2044037SPatrick Williams std::unordered_map<Path, std::unordered_map<Service, Interfaces>>; 43891c4769SDhruvaraj Subhashchandran 449bd334ffSPatrick Williams using ResourceNotFoundErr = 459bd334ffSPatrick Williams sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound; 469bd334ffSPatrick Williams using InvalidArgumentErr = 479bd334ffSPatrick Williams sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument; 483c6f29a0SDhruvaraj Subhashchandran 493e073ba6SPatrick Williams std::string getService(sdbusplus::bus_t& bus, const std::string& path) 503c6f29a0SDhruvaraj Subhashchandran { 511f0b715aSGeorge Liu auto mapper = bus.new_method_call(mapperBusName, mapperObjPath, mapperIntf, 521f0b715aSGeorge Liu "GetObject"); 531f0b715aSGeorge Liu mapper.append(path.c_str(), std::vector<std::string>({objMgrIntf})); 543c6f29a0SDhruvaraj Subhashchandran 55f2044037SPatrick Williams std::unordered_map<std::string, std::vector<std::string>> mapperResponse; 56151122aaSWilliam A. Kennington III try 57151122aaSWilliam A. Kennington III { 58d78de14dSGeorge Liu auto mapperResponseMsg = bus.call(mapper); 593c6f29a0SDhruvaraj Subhashchandran mapperResponseMsg.read(mapperResponse); 60151122aaSWilliam A. Kennington III } 613e073ba6SPatrick Williams catch (const sdbusplus::exception_t& e) 62151122aaSWilliam A. Kennington III { 63e9fb5c6aSGeorge Liu lg2::error( 64e9fb5c6aSGeorge Liu "Failed to parse getService mapper response, ERROR = {ERROR}", 65e9fb5c6aSGeorge Liu "ERROR", e); 669bd334ffSPatrick Williams using namespace xyz::openbmc_project::Common; 679bd334ffSPatrick Williams elog<ResourceNotFoundErr>(ResourceNotFound::RESOURCE(path.c_str())); 68151122aaSWilliam A. Kennington III } 693c6f29a0SDhruvaraj Subhashchandran if (mapperResponse.empty()) 703c6f29a0SDhruvaraj Subhashchandran { 719bd334ffSPatrick Williams using namespace xyz::openbmc_project::Common; 729bd334ffSPatrick Williams elog<ResourceNotFoundErr>(ResourceNotFound::RESOURCE(path.c_str())); 73c5e0f31cSGeorge Liu return {}; 743c6f29a0SDhruvaraj Subhashchandran } 753c6f29a0SDhruvaraj Subhashchandran 763c6f29a0SDhruvaraj Subhashchandran return mapperResponse.cbegin()->first; 773c6f29a0SDhruvaraj Subhashchandran } 783c6f29a0SDhruvaraj Subhashchandran 793e073ba6SPatrick Williams void action(sdbusplus::bus_t& bus, const std::string& path, bool assert) 8059b86cd7SDhruvaraj Subhashchandran { 813c6f29a0SDhruvaraj Subhashchandran std::string service; 823c6f29a0SDhruvaraj Subhashchandran try 833c6f29a0SDhruvaraj Subhashchandran { 841f0b715aSGeorge Liu std::string groups{ledGroups}; 85e77b8345SMatt Spinler groups.pop_back(); 86e77b8345SMatt Spinler service = getService(bus, groups); 873c6f29a0SDhruvaraj Subhashchandran } 889bd334ffSPatrick Williams catch (const ResourceNotFoundErr& e) 893c6f29a0SDhruvaraj Subhashchandran { 909bd334ffSPatrick Williams commit<ResourceNotFoundErr>(); 913c6f29a0SDhruvaraj Subhashchandran return; 923c6f29a0SDhruvaraj Subhashchandran } 933c6f29a0SDhruvaraj Subhashchandran 944bb15d80SGeorge Liu auto pos = path.rfind('/'); 953c6f29a0SDhruvaraj Subhashchandran if (pos == std::string::npos) 963c6f29a0SDhruvaraj Subhashchandran { 979bd334ffSPatrick Williams using namespace xyz::openbmc_project::Common; 989bd334ffSPatrick Williams report<InvalidArgumentErr>( 999bd334ffSPatrick Williams InvalidArgument::ARGUMENT_NAME("path"), 1009bd334ffSPatrick Williams InvalidArgument::ARGUMENT_VALUE(path.c_str())); 1013c6f29a0SDhruvaraj Subhashchandran return; 1023c6f29a0SDhruvaraj Subhashchandran } 1033c6f29a0SDhruvaraj Subhashchandran auto unit = path.substr(pos + 1); 1043c6f29a0SDhruvaraj Subhashchandran 1051f0b715aSGeorge Liu std::string ledPath = ledGroups + unit + '_' + LED_FAULT; 1063c6f29a0SDhruvaraj Subhashchandran 10791ac8d3aSPatrick Venture auto method = bus.new_method_call(service.c_str(), ledPath.c_str(), 10891ac8d3aSPatrick Venture "org.freedesktop.DBus.Properties", "Set"); 1093c6f29a0SDhruvaraj Subhashchandran method.append("xyz.openbmc_project.Led.Group"); 1103c6f29a0SDhruvaraj Subhashchandran method.append("Asserted"); 1113c6f29a0SDhruvaraj Subhashchandran 112a41d282aSPatrick Williams method.append(std::variant<bool>(assert)); 11308d613e7SAdriana Kobylak 11408d613e7SAdriana Kobylak try 11508d613e7SAdriana Kobylak { 1163c6f29a0SDhruvaraj Subhashchandran bus.call_noreply(method); 11708d613e7SAdriana Kobylak } 1183e073ba6SPatrick Williams catch (const sdbusplus::exception_t& e) 11908d613e7SAdriana Kobylak { 12008d613e7SAdriana Kobylak // Log an info message, system may not have all the LED Groups defined 121e9fb5c6aSGeorge Liu lg2::info("Failed to Assert LED Group, ERROR = {ERROR}", "ERROR", e); 12208d613e7SAdriana Kobylak } 1233c6f29a0SDhruvaraj Subhashchandran 12459b86cd7SDhruvaraj Subhashchandran return; 12559b86cd7SDhruvaraj Subhashchandran } 12659b86cd7SDhruvaraj Subhashchandran 1273e073ba6SPatrick Williams void Add::created(sdbusplus::message_t& msg) 12859b86cd7SDhruvaraj Subhashchandran { 1293eedbe44SPatrick Williams auto bus = msg.get_bus(); 1303c6f29a0SDhruvaraj Subhashchandran 131b2f253b7SMatt Spinler sdbusplus::message::object_path objectPath; 132b2f253b7SMatt Spinler InterfaceMap interfaces; 133151122aaSWilliam A. Kennington III try 134151122aaSWilliam A. Kennington III { 135b2f253b7SMatt Spinler msg.read(objectPath, interfaces); 136151122aaSWilliam A. Kennington III } 1373e073ba6SPatrick Williams catch (const sdbusplus::exception_t& e) 138151122aaSWilliam A. Kennington III { 139e9fb5c6aSGeorge Liu lg2::error("Failed to parse created message, ERROR = {ERROR}", "ERROR", 140e9fb5c6aSGeorge Liu e); 141151122aaSWilliam A. Kennington III return; 142151122aaSWilliam A. Kennington III } 1433c6f29a0SDhruvaraj Subhashchandran 144b2f253b7SMatt Spinler std::size_t found = objectPath.str.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 } 150a6e48929SAndrew Geissler auto iter = interfaces.find("xyz.openbmc_project.Association.Definitions"); 151b2f253b7SMatt Spinler if (iter == interfaces.end()) 1523c6f29a0SDhruvaraj Subhashchandran { 1533eedbe44SPatrick Williams return; 1543c6f29a0SDhruvaraj Subhashchandran } 1553c6f29a0SDhruvaraj Subhashchandran 1563d2b0d62SMatt Spinler // Nothing else shows when a specific error log 1573d2b0d62SMatt Spinler // has been created. Do it here. 158b4c82cf4SGeorge Liu lg2::info("{PATH} created", "PATH", objectPath); 1593d2b0d62SMatt Spinler 160a6e48929SAndrew Geissler auto attr = iter->second.find("Associations"); 161aebfde81SDhruvaraj Subhashchandran if (attr == iter->second.end()) 1623c6f29a0SDhruvaraj Subhashchandran { 1633eedbe44SPatrick Williams return; 1643c6f29a0SDhruvaraj Subhashchandran } 1653c6f29a0SDhruvaraj Subhashchandran 1665ebebeffSPatrick Williams auto& assocs = std::get<AssociationList>(attr->second); 1673c6f29a0SDhruvaraj Subhashchandran 1683c6f29a0SDhruvaraj Subhashchandran for (const auto& item : assocs) 1693c6f29a0SDhruvaraj Subhashchandran { 170*b6da7888SGeorge Liu if (std::get<1>(item) == CALLOUT_REV_ASSOCIATION) 1713c6f29a0SDhruvaraj Subhashchandran { 1723eedbe44SPatrick Williams removeWatches.emplace_back( 1733c6f29a0SDhruvaraj Subhashchandran std::make_unique<Remove>(bus, std::get<2>(item))); 174891c4769SDhruvaraj Subhashchandran action(bus, std::get<2>(item), true); 1753c6f29a0SDhruvaraj Subhashchandran } 1763c6f29a0SDhruvaraj Subhashchandran } 177aebfde81SDhruvaraj Subhashchandran 1783eedbe44SPatrick Williams return; 17959b86cd7SDhruvaraj Subhashchandran } 18059b86cd7SDhruvaraj Subhashchandran 1813e073ba6SPatrick Williams void getLoggingSubTree(sdbusplus::bus_t& bus, MapperResponseType& subtree) 182891c4769SDhruvaraj Subhashchandran { 183891c4769SDhruvaraj Subhashchandran auto depth = 0; 1841f0b715aSGeorge Liu auto mapperCall = bus.new_method_call(mapperBusName, mapperObjPath, 1851f0b715aSGeorge Liu mapperIntf, "GetSubTree"); 186891c4769SDhruvaraj Subhashchandran mapperCall.append("/"); 187891c4769SDhruvaraj Subhashchandran mapperCall.append(depth); 1881f0b715aSGeorge Liu mapperCall.append(std::vector<Interface>({logIntf})); 189891c4769SDhruvaraj Subhashchandran 19091122927SMatt Spinler try 19191122927SMatt Spinler { 192891c4769SDhruvaraj Subhashchandran auto mapperResponseMsg = bus.call(mapperCall); 19391122927SMatt Spinler mapperResponseMsg.read(subtree); 194151122aaSWilliam A. Kennington III } 1953e073ba6SPatrick Williams catch (const sdbusplus::exception_t& e) 196151122aaSWilliam A. Kennington III { 197e9fb5c6aSGeorge Liu lg2::error( 198e9fb5c6aSGeorge Liu "Failed to parse existing callouts subtree message, ERROR = {ERROR}", 199e9fb5c6aSGeorge Liu "ERROR", e); 20091122927SMatt Spinler } 20191122927SMatt Spinler } 20291122927SMatt Spinler 2033e073ba6SPatrick Williams void Add::processExistingCallouts(sdbusplus::bus_t& bus) 20491122927SMatt Spinler { 20591122927SMatt Spinler MapperResponseType mapperResponse; 20691122927SMatt Spinler 20791122927SMatt Spinler getLoggingSubTree(bus, mapperResponse); 208891c4769SDhruvaraj Subhashchandran if (mapperResponse.empty()) 209891c4769SDhruvaraj Subhashchandran { 210fc30e0c1SDhruvaraj Subhashchandran // No errors to process. 211891c4769SDhruvaraj Subhashchandran return; 212891c4769SDhruvaraj Subhashchandran } 213891c4769SDhruvaraj Subhashchandran 214891c4769SDhruvaraj Subhashchandran for (const auto& elem : mapperResponse) 215891c4769SDhruvaraj Subhashchandran { 21691ac8d3aSPatrick Venture auto method = bus.new_method_call( 21791ac8d3aSPatrick Venture elem.second.begin()->first.c_str(), elem.first.c_str(), 21891ac8d3aSPatrick Venture "org.freedesktop.DBus.Properties", "Get"); 219a6e48929SAndrew Geissler method.append("xyz.openbmc_project.Association.Definitions"); 220a6e48929SAndrew Geissler method.append("Associations"); 221891c4769SDhruvaraj Subhashchandran auto reply = bus.call(method); 222891c4769SDhruvaraj Subhashchandran if (reply.is_method_error()) 223891c4769SDhruvaraj Subhashchandran { 224891c4769SDhruvaraj Subhashchandran // do not stop, continue with next elog 225e9fb5c6aSGeorge Liu lg2::error("Error in getting associations"); 226891c4769SDhruvaraj Subhashchandran continue; 227891c4769SDhruvaraj Subhashchandran } 228891c4769SDhruvaraj Subhashchandran 229a41d282aSPatrick Williams std::variant<AssociationList> assoc; 230151122aaSWilliam A. Kennington III try 231151122aaSWilliam A. Kennington III { 232891c4769SDhruvaraj Subhashchandran reply.read(assoc); 233151122aaSWilliam A. Kennington III } 2343e073ba6SPatrick Williams catch (const sdbusplus::exception_t& e) 235151122aaSWilliam A. Kennington III { 236e9fb5c6aSGeorge Liu lg2::error( 237e9fb5c6aSGeorge Liu "Failed to parse existing callouts associations message, ERROR = {ERROR}", 238e9fb5c6aSGeorge Liu "ERROR", e); 239151122aaSWilliam A. Kennington III continue; 240151122aaSWilliam A. Kennington III } 2415ebebeffSPatrick Williams auto& assocs = std::get<AssociationList>(assoc); 242891c4769SDhruvaraj Subhashchandran 243891c4769SDhruvaraj Subhashchandran for (const auto& item : assocs) 244891c4769SDhruvaraj Subhashchandran { 245*b6da7888SGeorge Liu if (std::get<1>(item) == CALLOUT_REV_ASSOCIATION) 246891c4769SDhruvaraj Subhashchandran { 247891c4769SDhruvaraj Subhashchandran removeWatches.emplace_back( 248891c4769SDhruvaraj Subhashchandran std::make_unique<Remove>(bus, std::get<2>(item))); 249891c4769SDhruvaraj Subhashchandran action(bus, std::get<2>(item), true); 250891c4769SDhruvaraj Subhashchandran } 251891c4769SDhruvaraj Subhashchandran } 252891c4769SDhruvaraj Subhashchandran } 253891c4769SDhruvaraj Subhashchandran } 254891c4769SDhruvaraj Subhashchandran 2553e073ba6SPatrick Williams void Remove::removed(sdbusplus::message_t& msg) 25659b86cd7SDhruvaraj Subhashchandran { 2573eedbe44SPatrick Williams auto bus = msg.get_bus(); 2583c6f29a0SDhruvaraj Subhashchandran 2593eedbe44SPatrick Williams action(bus, inventoryPath, false); 2603eedbe44SPatrick Williams return; 26159b86cd7SDhruvaraj Subhashchandran } 26259b86cd7SDhruvaraj Subhashchandran 26359b86cd7SDhruvaraj Subhashchandran } // namespace monitor 26459b86cd7SDhruvaraj Subhashchandran } // namespace fault 26559b86cd7SDhruvaraj Subhashchandran } // namespace fru 26659b86cd7SDhruvaraj Subhashchandran } // namespace led 26759b86cd7SDhruvaraj Subhashchandran } // namespace phosphor 268