13c6f29a0SDhruvaraj Subhashchandran #include <phosphor-logging/elog.hpp> 2151122aaSWilliam A. Kennington III #include <sdbusplus/exception.hpp> 33c6f29a0SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Led/Fru/Monitor/error.hpp" 43c6f29a0SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Led/Mapper/error.hpp" 53c6f29a0SDhruvaraj Subhashchandran #include "elog-errors.hpp" 659b86cd7SDhruvaraj Subhashchandran #include "fru-fault-monitor.hpp" 73c6f29a0SDhruvaraj Subhashchandran 859b86cd7SDhruvaraj Subhashchandran namespace phosphor 959b86cd7SDhruvaraj Subhashchandran { 1059b86cd7SDhruvaraj Subhashchandran namespace led 1159b86cd7SDhruvaraj Subhashchandran { 1259b86cd7SDhruvaraj Subhashchandran namespace fru 1359b86cd7SDhruvaraj Subhashchandran { 1459b86cd7SDhruvaraj Subhashchandran namespace fault 1559b86cd7SDhruvaraj Subhashchandran { 1659b86cd7SDhruvaraj Subhashchandran namespace monitor 1759b86cd7SDhruvaraj Subhashchandran { 1859b86cd7SDhruvaraj Subhashchandran 193c6f29a0SDhruvaraj Subhashchandran using namespace phosphor::logging; 203c6f29a0SDhruvaraj Subhashchandran 213c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; 223c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_OBJ_PATH = "/xyz/openbmc_project/object_mapper"; 233c6f29a0SDhruvaraj Subhashchandran constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper"; 243c6f29a0SDhruvaraj Subhashchandran constexpr auto OBJMGR_IFACE = "org.freedesktop.DBus.ObjectManager"; 253c6f29a0SDhruvaraj Subhashchandran constexpr auto LED_GROUPS = "/xyz/openbmc_project/led/groups/"; 263c6f29a0SDhruvaraj Subhashchandran constexpr auto LOG_PATH = "/xyz/openbmc_project/logging"; 27891c4769SDhruvaraj Subhashchandran constexpr auto LOG_IFACE = "xyz.openbmc_project.Logging.Entry"; 283c6f29a0SDhruvaraj Subhashchandran 293c6f29a0SDhruvaraj Subhashchandran using AssociationList = std::vector<std::tuple< 303c6f29a0SDhruvaraj Subhashchandran std::string, std::string, std::string>>; 31aebfde81SDhruvaraj Subhashchandran using Attributes = sdbusplus::message::variant<bool,AssociationList>; 32aebfde81SDhruvaraj Subhashchandran using PropertyName = std::string; 33b2f253b7SMatt Spinler using PropertyMap = std::map<PropertyName, Attributes>; 34b2f253b7SMatt Spinler using InterfaceName = std::string; 35b2f253b7SMatt Spinler using InterfaceMap = std::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>; 41891c4769SDhruvaraj Subhashchandran using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>; 42891c4769SDhruvaraj Subhashchandran 433c6f29a0SDhruvaraj Subhashchandran using MethodErr = 443c6f29a0SDhruvaraj Subhashchandran sdbusplus::xyz::openbmc_project::Led::Mapper::Error::MethodError; 453c6f29a0SDhruvaraj Subhashchandran using ObjectNotFoundErr = 463c6f29a0SDhruvaraj Subhashchandran sdbusplus::xyz::openbmc_project::Led::Mapper::Error::ObjectNotFoundError; 473c6f29a0SDhruvaraj Subhashchandran using InventoryPathErr = 483c6f29a0SDhruvaraj Subhashchandran sdbusplus::xyz::openbmc_project:: 493c6f29a0SDhruvaraj Subhashchandran Led::Fru::Monitor::Error::InventoryPathError; 503c6f29a0SDhruvaraj Subhashchandran 513c6f29a0SDhruvaraj Subhashchandran std::string getService(sdbusplus::bus::bus& bus, 523c6f29a0SDhruvaraj Subhashchandran const std::string& path) 533c6f29a0SDhruvaraj Subhashchandran { 543c6f29a0SDhruvaraj Subhashchandran auto mapper = bus.new_method_call(MAPPER_BUSNAME, 553c6f29a0SDhruvaraj Subhashchandran MAPPER_OBJ_PATH, 563c6f29a0SDhruvaraj Subhashchandran MAPPER_IFACE, "GetObject"); 573c6f29a0SDhruvaraj Subhashchandran mapper.append(path.c_str(), std::vector<std::string>({OBJMGR_IFACE})); 583c6f29a0SDhruvaraj Subhashchandran auto mapperResponseMsg = bus.call(mapper); 593c6f29a0SDhruvaraj Subhashchandran if (mapperResponseMsg.is_method_error()) 603c6f29a0SDhruvaraj Subhashchandran { 613c6f29a0SDhruvaraj Subhashchandran using namespace xyz::openbmc_project::Led::Mapper; 623c6f29a0SDhruvaraj Subhashchandran elog<MethodErr>( 633c6f29a0SDhruvaraj Subhashchandran MethodError::METHOD_NAME("GetObject"), 643c6f29a0SDhruvaraj Subhashchandran MethodError::PATH(path.c_str()), 653c6f29a0SDhruvaraj Subhashchandran MethodError::INTERFACE( 663c6f29a0SDhruvaraj Subhashchandran OBJMGR_IFACE)); 673c6f29a0SDhruvaraj Subhashchandran } 683c6f29a0SDhruvaraj Subhashchandran 693c6f29a0SDhruvaraj Subhashchandran std::map<std::string, std::vector<std::string>> mapperResponse; 70151122aaSWilliam A. Kennington III try 71151122aaSWilliam A. Kennington III { 723c6f29a0SDhruvaraj Subhashchandran mapperResponseMsg.read(mapperResponse); 73151122aaSWilliam A. Kennington III } 74151122aaSWilliam A. Kennington III catch (const sdbusplus::exception::SdBusError& e) 75151122aaSWilliam A. Kennington III { 76151122aaSWilliam A. Kennington III log<level::ERR>("Failed to parse getService mapper response", 77151122aaSWilliam A. Kennington III entry("ERROR=%s", e.what()), 78151122aaSWilliam A. Kennington III entry("REPLY_SIG=%s", mapperResponseMsg.get_signature())); 79151122aaSWilliam A. Kennington III using namespace xyz::openbmc_project::Led::Mapper; 80151122aaSWilliam A. Kennington III elog<ObjectNotFoundErr>( 81151122aaSWilliam A. Kennington III ObjectNotFoundError::METHOD_NAME("GetObject"), 82151122aaSWilliam A. Kennington III ObjectNotFoundError::PATH(path.c_str()), 83151122aaSWilliam A. Kennington III ObjectNotFoundError::INTERFACE( 84151122aaSWilliam A. Kennington III OBJMGR_IFACE)); 85151122aaSWilliam A. Kennington III } 863c6f29a0SDhruvaraj Subhashchandran if (mapperResponse.empty()) 873c6f29a0SDhruvaraj Subhashchandran { 883c6f29a0SDhruvaraj Subhashchandran using namespace xyz::openbmc_project::Led::Mapper; 893c6f29a0SDhruvaraj Subhashchandran elog<ObjectNotFoundErr>( 903c6f29a0SDhruvaraj Subhashchandran ObjectNotFoundError::METHOD_NAME("GetObject"), 913c6f29a0SDhruvaraj Subhashchandran ObjectNotFoundError::PATH(path.c_str()), 923c6f29a0SDhruvaraj Subhashchandran ObjectNotFoundError::INTERFACE( 933c6f29a0SDhruvaraj Subhashchandran OBJMGR_IFACE)); 943c6f29a0SDhruvaraj Subhashchandran } 953c6f29a0SDhruvaraj Subhashchandran 963c6f29a0SDhruvaraj Subhashchandran return mapperResponse.cbegin()->first; 973c6f29a0SDhruvaraj Subhashchandran } 983c6f29a0SDhruvaraj Subhashchandran 9959b86cd7SDhruvaraj Subhashchandran void action(sdbusplus::bus::bus& bus, 1003c6f29a0SDhruvaraj Subhashchandran const std::string& path, 10159b86cd7SDhruvaraj Subhashchandran bool assert) 10259b86cd7SDhruvaraj Subhashchandran { 1033c6f29a0SDhruvaraj Subhashchandran std::string service; 1043c6f29a0SDhruvaraj Subhashchandran try 1053c6f29a0SDhruvaraj Subhashchandran { 106*e77b8345SMatt Spinler std::string groups{LED_GROUPS}; 107*e77b8345SMatt Spinler groups.pop_back(); 108*e77b8345SMatt Spinler service = getService(bus, groups); 1093c6f29a0SDhruvaraj Subhashchandran } 1103c6f29a0SDhruvaraj Subhashchandran catch (MethodErr& e) 1113c6f29a0SDhruvaraj Subhashchandran { 1123c6f29a0SDhruvaraj Subhashchandran commit<MethodErr>(); 1133c6f29a0SDhruvaraj Subhashchandran return; 1143c6f29a0SDhruvaraj Subhashchandran } 1153c6f29a0SDhruvaraj Subhashchandran catch (ObjectNotFoundErr& e) 1163c6f29a0SDhruvaraj Subhashchandran { 1173c6f29a0SDhruvaraj Subhashchandran commit<ObjectNotFoundErr>(); 1183c6f29a0SDhruvaraj Subhashchandran return; 1193c6f29a0SDhruvaraj Subhashchandran } 1203c6f29a0SDhruvaraj Subhashchandran 1213c6f29a0SDhruvaraj Subhashchandran auto pos = path.rfind("/"); 1223c6f29a0SDhruvaraj Subhashchandran if (pos == std::string::npos) 1233c6f29a0SDhruvaraj Subhashchandran { 1243c6f29a0SDhruvaraj Subhashchandran using namespace xyz::openbmc_project::Led::Fru::Monitor; 1253c6f29a0SDhruvaraj Subhashchandran report<InventoryPathErr>( 1263c6f29a0SDhruvaraj Subhashchandran InventoryPathError::PATH( 1273c6f29a0SDhruvaraj Subhashchandran path.c_str())); 1283c6f29a0SDhruvaraj Subhashchandran return; 1293c6f29a0SDhruvaraj Subhashchandran } 1303c6f29a0SDhruvaraj Subhashchandran auto unit = path.substr(pos + 1); 1313c6f29a0SDhruvaraj Subhashchandran 1323c6f29a0SDhruvaraj Subhashchandran std::string ledPath = LED_GROUPS + 1333c6f29a0SDhruvaraj Subhashchandran unit + '_' + LED_FAULT; 1343c6f29a0SDhruvaraj Subhashchandran 1353c6f29a0SDhruvaraj Subhashchandran auto method = bus.new_method_call(service.c_str(), 1363c6f29a0SDhruvaraj Subhashchandran ledPath.c_str(), 1373c6f29a0SDhruvaraj Subhashchandran "org.freedesktop.DBus.Properties", 1383c6f29a0SDhruvaraj Subhashchandran "Set"); 1393c6f29a0SDhruvaraj Subhashchandran method.append("xyz.openbmc_project.Led.Group"); 1403c6f29a0SDhruvaraj Subhashchandran method.append("Asserted"); 1413c6f29a0SDhruvaraj Subhashchandran 1423c6f29a0SDhruvaraj Subhashchandran method.append(sdbusplus::message::variant<bool>(assert)); 14308d613e7SAdriana Kobylak 14408d613e7SAdriana Kobylak try 14508d613e7SAdriana Kobylak { 1463c6f29a0SDhruvaraj Subhashchandran bus.call_noreply(method); 14708d613e7SAdriana Kobylak } 14808d613e7SAdriana Kobylak catch (const sdbusplus::exception::SdBusError& e) 14908d613e7SAdriana Kobylak { 15008d613e7SAdriana Kobylak // Log an info message, system may not have all the LED Groups defined 15108d613e7SAdriana Kobylak log<level::INFO>("Failed to Assert LED Group", 15208d613e7SAdriana Kobylak entry("ERROR=%s", e.what())); 15308d613e7SAdriana Kobylak } 1543c6f29a0SDhruvaraj Subhashchandran 15559b86cd7SDhruvaraj Subhashchandran return; 15659b86cd7SDhruvaraj Subhashchandran } 15759b86cd7SDhruvaraj Subhashchandran 1583eedbe44SPatrick Williams void Add::created(sdbusplus::message::message& msg) 15959b86cd7SDhruvaraj Subhashchandran { 1603eedbe44SPatrick Williams auto bus = msg.get_bus(); 1613c6f29a0SDhruvaraj Subhashchandran 162b2f253b7SMatt Spinler sdbusplus::message::object_path objectPath; 163b2f253b7SMatt Spinler InterfaceMap interfaces; 164151122aaSWilliam A. Kennington III try 165151122aaSWilliam A. Kennington III { 166b2f253b7SMatt Spinler msg.read(objectPath, interfaces); 167151122aaSWilliam A. Kennington III } 168151122aaSWilliam A. Kennington III catch (const sdbusplus::exception::SdBusError& e) 169151122aaSWilliam A. Kennington III { 170151122aaSWilliam A. Kennington III log<level::ERR>("Failed to parse created message", 171151122aaSWilliam A. Kennington III entry("ERROR=%s", e.what()), 172151122aaSWilliam A. Kennington III entry("REPLY_SIG=%s", msg.get_signature())); 173151122aaSWilliam A. Kennington III return; 174151122aaSWilliam A. Kennington III } 1753c6f29a0SDhruvaraj Subhashchandran 176b2f253b7SMatt Spinler std::size_t found = objectPath.str.find(ELOG_ENTRY); 1773c6f29a0SDhruvaraj Subhashchandran if (found == std::string::npos) 1783c6f29a0SDhruvaraj Subhashchandran { 1793c6f29a0SDhruvaraj Subhashchandran //Not a new error entry skip 1803eedbe44SPatrick Williams return; 1813c6f29a0SDhruvaraj Subhashchandran } 182b2f253b7SMatt Spinler auto iter = interfaces.find("org.openbmc.Associations"); 183b2f253b7SMatt Spinler if (iter == interfaces.end()) 1843c6f29a0SDhruvaraj Subhashchandran { 1853eedbe44SPatrick Williams return; 1863c6f29a0SDhruvaraj Subhashchandran } 1873c6f29a0SDhruvaraj Subhashchandran 1883d2b0d62SMatt Spinler //Nothing else shows when a specific error log 1893d2b0d62SMatt Spinler //has been created. Do it here. 190b2f253b7SMatt Spinler std::string message{objectPath.str + " created"}; 1913d2b0d62SMatt Spinler log<level::INFO>(message.c_str()); 1923d2b0d62SMatt Spinler 193aebfde81SDhruvaraj Subhashchandran auto attr = iter->second.find("associations"); 194aebfde81SDhruvaraj Subhashchandran if (attr == iter->second.end()) 1953c6f29a0SDhruvaraj Subhashchandran { 1963eedbe44SPatrick Williams return; 1973c6f29a0SDhruvaraj Subhashchandran } 1983c6f29a0SDhruvaraj Subhashchandran 199aebfde81SDhruvaraj Subhashchandran auto& assocs = 200aebfde81SDhruvaraj Subhashchandran sdbusplus::message::variant_ns::get<AssociationList>(attr->second); 2013c6f29a0SDhruvaraj Subhashchandran if (assocs.empty()) 2023c6f29a0SDhruvaraj Subhashchandran { 2033c6f29a0SDhruvaraj Subhashchandran //No associations skip 2043eedbe44SPatrick Williams return; 2053c6f29a0SDhruvaraj Subhashchandran } 2063c6f29a0SDhruvaraj Subhashchandran 2073c6f29a0SDhruvaraj Subhashchandran for (const auto& item : assocs) 2083c6f29a0SDhruvaraj Subhashchandran { 2093c6f29a0SDhruvaraj Subhashchandran if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0) 2103c6f29a0SDhruvaraj Subhashchandran { 2113eedbe44SPatrick Williams removeWatches.emplace_back( 2123c6f29a0SDhruvaraj Subhashchandran std::make_unique<Remove>(bus, std::get<2>(item))); 213891c4769SDhruvaraj Subhashchandran action(bus, std::get<2>(item), true); 2143c6f29a0SDhruvaraj Subhashchandran } 2153c6f29a0SDhruvaraj Subhashchandran } 216aebfde81SDhruvaraj Subhashchandran 2173eedbe44SPatrick Williams return; 21859b86cd7SDhruvaraj Subhashchandran } 21959b86cd7SDhruvaraj Subhashchandran 220891c4769SDhruvaraj Subhashchandran void Add::processExistingCallouts(sdbusplus::bus::bus& bus) 221891c4769SDhruvaraj Subhashchandran { 222891c4769SDhruvaraj Subhashchandran auto depth = 0; 223891c4769SDhruvaraj Subhashchandran auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, 224891c4769SDhruvaraj Subhashchandran MAPPER_OBJ_PATH, 225891c4769SDhruvaraj Subhashchandran MAPPER_IFACE, 226891c4769SDhruvaraj Subhashchandran "GetSubTree"); 227891c4769SDhruvaraj Subhashchandran mapperCall.append("/"); 228891c4769SDhruvaraj Subhashchandran mapperCall.append(depth); 229891c4769SDhruvaraj Subhashchandran mapperCall.append(std::vector<Interface>({LOG_IFACE})); 230891c4769SDhruvaraj Subhashchandran 231891c4769SDhruvaraj Subhashchandran auto mapperResponseMsg = bus.call(mapperCall); 232891c4769SDhruvaraj Subhashchandran if (mapperResponseMsg.is_method_error()) 233891c4769SDhruvaraj Subhashchandran { 234891c4769SDhruvaraj Subhashchandran using namespace xyz::openbmc_project::Led::Mapper; 235891c4769SDhruvaraj Subhashchandran report<MethodErr>( 236891c4769SDhruvaraj Subhashchandran MethodError::METHOD_NAME("GetSubTree"), 237891c4769SDhruvaraj Subhashchandran MethodError::PATH(MAPPER_OBJ_PATH), 238891c4769SDhruvaraj Subhashchandran MethodError::INTERFACE( 239891c4769SDhruvaraj Subhashchandran OBJMGR_IFACE)); 240891c4769SDhruvaraj Subhashchandran return; 241891c4769SDhruvaraj Subhashchandran } 242891c4769SDhruvaraj Subhashchandran 243891c4769SDhruvaraj Subhashchandran MapperResponseType mapperResponse; 244151122aaSWilliam A. Kennington III try 245151122aaSWilliam A. Kennington III { 246891c4769SDhruvaraj Subhashchandran mapperResponseMsg.read(mapperResponse); 247151122aaSWilliam A. Kennington III } 248151122aaSWilliam A. Kennington III catch (const sdbusplus::exception::SdBusError& e) 249151122aaSWilliam A. Kennington III { 250151122aaSWilliam A. Kennington III log<level::ERR>("Failed to parse existing callouts subtree message", 251151122aaSWilliam A. Kennington III entry("ERROR=%s", e.what()), 252151122aaSWilliam A. Kennington III entry("REPLY_SIG=%s", mapperResponseMsg.get_signature())); 253151122aaSWilliam A. Kennington III return; 254151122aaSWilliam A. Kennington III } 255891c4769SDhruvaraj Subhashchandran if (mapperResponse.empty()) 256891c4769SDhruvaraj Subhashchandran { 257fc30e0c1SDhruvaraj Subhashchandran //No errors to process. 258891c4769SDhruvaraj Subhashchandran return; 259891c4769SDhruvaraj Subhashchandran } 260891c4769SDhruvaraj Subhashchandran 261891c4769SDhruvaraj Subhashchandran for (const auto& elem : mapperResponse) 262891c4769SDhruvaraj Subhashchandran { 263891c4769SDhruvaraj Subhashchandran auto method = bus.new_method_call(elem.second.begin()->first.c_str(), 264891c4769SDhruvaraj Subhashchandran elem.first.c_str(), 265891c4769SDhruvaraj Subhashchandran "org.freedesktop.DBus.Properties", 266891c4769SDhruvaraj Subhashchandran "Get"); 267891c4769SDhruvaraj Subhashchandran method.append("org.openbmc.Associations"); 268891c4769SDhruvaraj Subhashchandran method.append("associations"); 269891c4769SDhruvaraj Subhashchandran auto reply = bus.call(method); 270891c4769SDhruvaraj Subhashchandran if (reply.is_method_error()) 271891c4769SDhruvaraj Subhashchandran { 272891c4769SDhruvaraj Subhashchandran //do not stop, continue with next elog 273891c4769SDhruvaraj Subhashchandran log<level::ERR>("Error in getting associations"); 274891c4769SDhruvaraj Subhashchandran continue; 275891c4769SDhruvaraj Subhashchandran } 276891c4769SDhruvaraj Subhashchandran 277891c4769SDhruvaraj Subhashchandran sdbusplus::message::variant<AssociationList> assoc; 278151122aaSWilliam A. Kennington III try 279151122aaSWilliam A. Kennington III { 280891c4769SDhruvaraj Subhashchandran reply.read(assoc); 281151122aaSWilliam A. Kennington III } 282151122aaSWilliam A. Kennington III catch (const sdbusplus::exception::SdBusError& e) 283151122aaSWilliam A. Kennington III { 284151122aaSWilliam A. Kennington III log<level::ERR>("Failed to parse existing callouts associations message", 285151122aaSWilliam A. Kennington III entry("ERROR=%s", e.what()), 286151122aaSWilliam A. Kennington III entry("REPLY_SIG=%s", reply.get_signature())); 287151122aaSWilliam A. Kennington III continue; 288151122aaSWilliam A. Kennington III } 289891c4769SDhruvaraj Subhashchandran auto& assocs = assoc.get<AssociationList>(); 290891c4769SDhruvaraj Subhashchandran if (assocs.empty()) 291891c4769SDhruvaraj Subhashchandran { 292891c4769SDhruvaraj Subhashchandran //no associations, skip 293891c4769SDhruvaraj Subhashchandran continue; 294891c4769SDhruvaraj Subhashchandran } 295891c4769SDhruvaraj Subhashchandran 296891c4769SDhruvaraj Subhashchandran for (const auto& item : assocs) 297891c4769SDhruvaraj Subhashchandran { 298891c4769SDhruvaraj Subhashchandran if (std::get<1>(item).compare(CALLOUT_REV_ASSOCIATION) == 0) 299891c4769SDhruvaraj Subhashchandran { 300891c4769SDhruvaraj Subhashchandran removeWatches.emplace_back( 301891c4769SDhruvaraj Subhashchandran std::make_unique<Remove>(bus, std::get<2>(item))); 302891c4769SDhruvaraj Subhashchandran action(bus, std::get<2>(item), true); 303891c4769SDhruvaraj Subhashchandran } 304891c4769SDhruvaraj Subhashchandran } 305891c4769SDhruvaraj Subhashchandran } 306891c4769SDhruvaraj Subhashchandran } 307891c4769SDhruvaraj Subhashchandran 3083eedbe44SPatrick Williams void Remove::removed(sdbusplus::message::message& msg) 30959b86cd7SDhruvaraj Subhashchandran { 3103eedbe44SPatrick Williams auto bus = msg.get_bus(); 3113c6f29a0SDhruvaraj Subhashchandran 3123eedbe44SPatrick Williams action(bus, inventoryPath, false); 3133eedbe44SPatrick Williams return; 31459b86cd7SDhruvaraj Subhashchandran } 31559b86cd7SDhruvaraj Subhashchandran 31659b86cd7SDhruvaraj Subhashchandran }//namespace monitor 31759b86cd7SDhruvaraj Subhashchandran }//namespace fault 31859b86cd7SDhruvaraj Subhashchandran }//namespace fru 31959b86cd7SDhruvaraj Subhashchandran }//namespace led 32059b86cd7SDhruvaraj Subhashchandran }//namespace phosphor 321