1 #include "config.h" 2 3 #include "chassis_manager.hpp" 4 5 #include <phosphor-logging/lg2.hpp> 6 7 using namespace phosphor::logging; 8 9 namespace phosphor::power::chassis_manager 10 { 11 using namespace phosphor::power::util; 12 constexpr auto managerBusName = 13 "xyz.openbmc_project.Power.MultiChassisPSUMonitor"; 14 constexpr auto IBMCFFPSInterface = 15 "xyz.openbmc_project.Configuration.IBMCFFPSConnector"; 16 constexpr auto supportedConfIntf = 17 "xyz.openbmc_project.Configuration.SupportedConfiguration"; 18 19 ChassisManager::ChassisManager(sdbusplus::bus_t& bus, 20 const sdeventplus::Event& e) : 21 bus(bus), eventLoop(e) 22 { 23 // Subscribe to InterfacesAdded before doing a property read, otherwise 24 // the interface could be created after the read attempt but before the 25 // match is created. 26 entityManagerIfacesAddedMatch = std::make_unique<sdbusplus::bus::match_t>( 27 bus, 28 sdbusplus::bus::match::rules::interfacesAdded() + 29 sdbusplus::bus::match::rules::sender( 30 "xyz.openbmc_project.EntityManager"), 31 std::bind(&ChassisManager::entityManagerIfaceAdded, this, 32 std::placeholders::_1)); 33 34 initializeChassisList(); 35 36 // Request the bus name before the analyze() function, which is the one that 37 // determines the brownout condition and sets the status d-bus property. 38 bus.request_name(managerBusName); 39 40 using namespace sdeventplus; 41 auto interval = std::chrono::milliseconds(1000); 42 timer = std::make_unique<utility::Timer<ClockId::Monotonic>>( 43 e, std::bind(&ChassisManager::analyze, this), interval); 44 initChassisPowerMonitoring(); 45 } 46 47 void ChassisManager::entityManagerIfaceAdded(sdbusplus::message_t& msg) 48 { 49 try 50 { 51 phosphor::power::chassis::Chassis* chassisMatchPtr = nullptr; 52 sdbusplus::message::object_path objPath; 53 std::map<std::string, std::map<std::string, util::DbusVariant>> 54 interfaces; 55 msg.read(objPath, interfaces); 56 57 std::string objPathStr = objPath; 58 59 auto itInterface = interfaces.find(supportedConfIntf); 60 if (itInterface != interfaces.cend()) 61 { 62 lg2::info("InterfacesAdded supportedConfIntf- objPathStr= {OBJ}", 63 "OBJ", objPathStr); 64 auto myChassisId = getParentEMUniqueId(bus, objPathStr); 65 chassisMatchPtr = getMatchingChassisPtr(myChassisId); 66 if (chassisMatchPtr) 67 { 68 lg2::debug("InterfacesAdded for: {SUPPORTED_CONFIGURATION}", 69 "SUPPORTED_CONFIGURATION", supportedConfIntf); 70 chassisMatchPtr->supportedConfigurationInterfaceAdded( 71 itInterface->second); 72 } 73 } 74 itInterface = interfaces.find(IBMCFFPSInterface); 75 if (itInterface != interfaces.cend()) 76 { 77 lg2::debug("InterfacesAdded IBMCFFPSInterface- objPathStr= {OBJ}", 78 "OBJ", objPathStr); 79 auto myChassisId = getParentEMUniqueId(bus, objPathStr); 80 chassisMatchPtr = getMatchingChassisPtr(myChassisId); 81 if (chassisMatchPtr) 82 { 83 lg2::info("InterfacesAdded for: {IBMCFFPSINTERFACE}", 84 "IBMCFFPSINTERFACE", IBMCFFPSInterface); 85 chassisMatchPtr->psuInterfaceAdded(itInterface->second); 86 } 87 } 88 if (chassisMatchPtr != nullptr) 89 { 90 lg2::debug( 91 "InterfacesAdded validatePsuConfigAndInterfacesProcessed()"); 92 chassisMatchPtr->validatePsuConfigAndInterfacesProcessed(); 93 } 94 } 95 catch (const std::exception& e) 96 { 97 // Ignore, the property may be of a different type than expected. 98 } 99 } 100 101 phosphor::power::chassis::Chassis* ChassisManager::getMatchingChassisPtr( 102 uint64_t chassisId) 103 { 104 for (const auto& chassisPtr : listOfChassis) 105 { 106 if (chassisPtr->getChassisId() == chassisId) 107 { 108 return chassisPtr.get(); 109 } 110 } 111 lg2::debug("Chassis ID {ID} not found", "ID", chassisId); 112 return nullptr; 113 } 114 115 void ChassisManager::analyze() 116 { 117 for (const auto& chassis : listOfChassis) 118 { 119 chassis->analyze(); 120 } 121 } 122 123 void ChassisManager::initializeChassisList() 124 { 125 try 126 { 127 auto chassisPathList = getChassisInventoryPaths(bus); 128 for (const auto& chassisPath : chassisPathList) 129 { 130 lg2::info( 131 "ChassisManager::initializeChassisList chassisPath= {CHASSIS_PATH}", 132 "CHASSIS_PATH", chassisPath); 133 auto chassis = std::make_unique<phosphor::power::chassis::Chassis>( 134 bus, chassisPath, eventLoop); 135 listOfChassis.push_back(std::move(chassis)); 136 } 137 } 138 catch (const sdbusplus::exception_t& e) 139 { 140 lg2::error("Failed to initialize chassis list, error: {ERROR}", "ERROR", 141 e); 142 } 143 } 144 145 void ChassisManager::initChassisPowerMonitoring() 146 { 147 for (const auto& chassis : listOfChassis) 148 { 149 chassis->initPowerMonitoring(); 150 } 151 } 152 153 } // namespace phosphor::power::chassis_manager 154