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