xref: /openbmc/phosphor-power/phosphor-power-supply/chassis_manager.cpp (revision 9ed0f38e1d59564106c6020b854416ece6753776)
1348168b6SFaisal Awada #include "config.h"
2348168b6SFaisal Awada 
3348168b6SFaisal Awada #include "chassis_manager.hpp"
4348168b6SFaisal Awada 
5348168b6SFaisal Awada #include <phosphor-logging/lg2.hpp>
6*9ed0f38eSFaisal Awada 
7348168b6SFaisal Awada using namespace phosphor::logging;
8348168b6SFaisal Awada 
9348168b6SFaisal Awada namespace phosphor::power::chassis_manager
10348168b6SFaisal Awada {
11348168b6SFaisal Awada using namespace phosphor::power::util;
12348168b6SFaisal Awada constexpr auto managerBusName =
13348168b6SFaisal Awada     "xyz.openbmc_project.Power.MultiChassisPSUMonitor";
14348168b6SFaisal Awada constexpr auto IBMCFFPSInterface =
15348168b6SFaisal Awada     "xyz.openbmc_project.Configuration.IBMCFFPSConnector";
16348168b6SFaisal Awada constexpr auto supportedConfIntf =
17348168b6SFaisal Awada     "xyz.openbmc_project.Configuration.SupportedConfiguration";
18348168b6SFaisal Awada 
ChassisManager(sdbusplus::bus_t & bus,const sdeventplus::Event & e)19348168b6SFaisal Awada ChassisManager::ChassisManager(sdbusplus::bus_t& bus,
20348168b6SFaisal Awada                                const sdeventplus::Event& e) :
21348168b6SFaisal Awada     bus(bus), eventLoop(e)
22348168b6SFaisal Awada {
23348168b6SFaisal Awada     // Subscribe to InterfacesAdded before doing a property read, otherwise
24348168b6SFaisal Awada     // the interface could be created after the read attempt but before the
25348168b6SFaisal Awada     // match is created.
26348168b6SFaisal Awada     entityManagerIfacesAddedMatch = std::make_unique<sdbusplus::bus::match_t>(
27348168b6SFaisal Awada         bus,
28348168b6SFaisal Awada         sdbusplus::bus::match::rules::interfacesAdded() +
29348168b6SFaisal Awada             sdbusplus::bus::match::rules::sender(
30348168b6SFaisal Awada                 "xyz.openbmc_project.EntityManager"),
31348168b6SFaisal Awada         std::bind(&ChassisManager::entityManagerIfaceAdded, this,
32348168b6SFaisal Awada                   std::placeholders::_1));
33348168b6SFaisal Awada 
34348168b6SFaisal Awada     initializeChassisList();
35348168b6SFaisal Awada 
36348168b6SFaisal Awada     // Request the bus name before the analyze() function, which is the one that
37348168b6SFaisal Awada     // determines the brownout condition and sets the status d-bus property.
38348168b6SFaisal Awada     bus.request_name(managerBusName);
39348168b6SFaisal Awada 
40348168b6SFaisal Awada     using namespace sdeventplus;
41348168b6SFaisal Awada     auto interval = std::chrono::milliseconds(1000);
42348168b6SFaisal Awada     timer = std::make_unique<utility::Timer<ClockId::Monotonic>>(
43348168b6SFaisal Awada         e, std::bind(&ChassisManager::analyze, this), interval);
44*9ed0f38eSFaisal Awada     initChassisPowerMonitoring();
45348168b6SFaisal Awada }
46348168b6SFaisal Awada 
entityManagerIfaceAdded(sdbusplus::message_t & msg)47348168b6SFaisal Awada void ChassisManager::entityManagerIfaceAdded(sdbusplus::message_t& msg)
48348168b6SFaisal Awada {
49348168b6SFaisal Awada     try
50348168b6SFaisal Awada     {
51348168b6SFaisal Awada         phosphor::power::chassis::Chassis* chassisMatchPtr = nullptr;
52348168b6SFaisal Awada         sdbusplus::message::object_path objPath;
53348168b6SFaisal Awada         std::map<std::string, std::map<std::string, util::DbusVariant>>
54348168b6SFaisal Awada             interfaces;
55348168b6SFaisal Awada         msg.read(objPath, interfaces);
56348168b6SFaisal Awada 
57348168b6SFaisal Awada         std::string objPathStr = objPath;
58348168b6SFaisal Awada 
59348168b6SFaisal Awada         auto itInterface = interfaces.find(supportedConfIntf);
60348168b6SFaisal Awada         if (itInterface != interfaces.cend())
61348168b6SFaisal Awada         {
62348168b6SFaisal Awada             lg2::info("InterfacesAdded supportedConfIntf- objPathStr= {OBJ}",
63348168b6SFaisal Awada                       "OBJ", objPathStr);
64348168b6SFaisal Awada             auto myChassisId = getParentEMUniqueId(bus, objPathStr);
65348168b6SFaisal Awada             chassisMatchPtr = getMatchingChassisPtr(myChassisId);
66348168b6SFaisal Awada             if (chassisMatchPtr)
67348168b6SFaisal Awada             {
68348168b6SFaisal Awada                 lg2::debug("InterfacesAdded for: {SUPPORTED_CONFIGURATION}",
69348168b6SFaisal Awada                            "SUPPORTED_CONFIGURATION", supportedConfIntf);
70*9ed0f38eSFaisal Awada                 chassisMatchPtr->supportedConfigurationInterfaceAdded(
71*9ed0f38eSFaisal Awada                     itInterface->second);
72348168b6SFaisal Awada             }
73348168b6SFaisal Awada         }
74348168b6SFaisal Awada         itInterface = interfaces.find(IBMCFFPSInterface);
75348168b6SFaisal Awada         if (itInterface != interfaces.cend())
76348168b6SFaisal Awada         {
77348168b6SFaisal Awada             lg2::debug("InterfacesAdded IBMCFFPSInterface- objPathStr= {OBJ}",
78348168b6SFaisal Awada                        "OBJ", objPathStr);
79348168b6SFaisal Awada             auto myChassisId = getParentEMUniqueId(bus, objPathStr);
80348168b6SFaisal Awada             chassisMatchPtr = getMatchingChassisPtr(myChassisId);
81348168b6SFaisal Awada             if (chassisMatchPtr)
82348168b6SFaisal Awada             {
83348168b6SFaisal Awada                 lg2::info("InterfacesAdded for: {IBMCFFPSINTERFACE}",
84348168b6SFaisal Awada                           "IBMCFFPSINTERFACE", IBMCFFPSInterface);
85*9ed0f38eSFaisal Awada                 chassisMatchPtr->psuInterfaceAdded(itInterface->second);
86348168b6SFaisal Awada             }
87348168b6SFaisal Awada         }
88348168b6SFaisal Awada         if (chassisMatchPtr != nullptr)
89348168b6SFaisal Awada         {
90348168b6SFaisal Awada             lg2::debug(
91348168b6SFaisal Awada                 "InterfacesAdded validatePsuConfigAndInterfacesProcessed()");
92*9ed0f38eSFaisal Awada             chassisMatchPtr->validatePsuConfigAndInterfacesProcessed();
93348168b6SFaisal Awada         }
94348168b6SFaisal Awada     }
95348168b6SFaisal Awada     catch (const std::exception& e)
96348168b6SFaisal Awada     {
97348168b6SFaisal Awada         // Ignore, the property may be of a different type than expected.
98348168b6SFaisal Awada     }
99348168b6SFaisal Awada }
100348168b6SFaisal Awada 
getMatchingChassisPtr(uint64_t chassisId)101348168b6SFaisal Awada phosphor::power::chassis::Chassis* ChassisManager::getMatchingChassisPtr(
102348168b6SFaisal Awada     uint64_t chassisId)
103348168b6SFaisal Awada {
104348168b6SFaisal Awada     for (const auto& chassisPtr : listOfChassis)
105348168b6SFaisal Awada     {
106348168b6SFaisal Awada         if (chassisPtr->getChassisId() == chassisId)
107348168b6SFaisal Awada         {
108348168b6SFaisal Awada             return chassisPtr.get();
109348168b6SFaisal Awada         }
110348168b6SFaisal Awada     }
111348168b6SFaisal Awada     lg2::debug("Chassis ID {ID} not found", "ID", chassisId);
112348168b6SFaisal Awada     return nullptr;
113348168b6SFaisal Awada }
114348168b6SFaisal Awada 
analyze()115348168b6SFaisal Awada void ChassisManager::analyze()
116348168b6SFaisal Awada {
117348168b6SFaisal Awada     for (const auto& chassis : listOfChassis)
118348168b6SFaisal Awada     {
119348168b6SFaisal Awada         chassis->analyze();
120348168b6SFaisal Awada     }
121348168b6SFaisal Awada }
122348168b6SFaisal Awada 
initializeChassisList()123348168b6SFaisal Awada void ChassisManager::initializeChassisList()
124348168b6SFaisal Awada {
125348168b6SFaisal Awada     try
126348168b6SFaisal Awada     {
127348168b6SFaisal Awada         auto chassisPathList = getChassisInventoryPaths(bus);
128348168b6SFaisal Awada         for (const auto& chassisPath : chassisPathList)
129348168b6SFaisal Awada         {
130348168b6SFaisal Awada             lg2::info(
131348168b6SFaisal Awada                 "ChassisManager::initializeChassisList chassisPath= {CHASSIS_PATH}",
132348168b6SFaisal Awada                 "CHASSIS_PATH", chassisPath);
133348168b6SFaisal Awada             auto chassis = std::make_unique<phosphor::power::chassis::Chassis>(
134348168b6SFaisal Awada                 bus, chassisPath, eventLoop);
135348168b6SFaisal Awada             listOfChassis.push_back(std::move(chassis));
136348168b6SFaisal Awada         }
137348168b6SFaisal Awada     }
138348168b6SFaisal Awada     catch (const sdbusplus::exception_t& e)
139348168b6SFaisal Awada     {
140348168b6SFaisal Awada         lg2::error("Failed to initialize chassis list, error: {ERROR}", "ERROR",
141348168b6SFaisal Awada                    e);
142348168b6SFaisal Awada     }
143348168b6SFaisal Awada }
144*9ed0f38eSFaisal Awada 
initChassisPowerMonitoring()145*9ed0f38eSFaisal Awada void ChassisManager::initChassisPowerMonitoring()
146*9ed0f38eSFaisal Awada {
147*9ed0f38eSFaisal Awada     for (const auto& chassis : listOfChassis)
148*9ed0f38eSFaisal Awada     {
149*9ed0f38eSFaisal Awada         chassis->initPowerMonitoring();
150*9ed0f38eSFaisal Awada     }
151*9ed0f38eSFaisal Awada }
152*9ed0f38eSFaisal Awada 
153348168b6SFaisal Awada } // namespace phosphor::power::chassis_manager
154