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