xref: /openbmc/phosphor-power/phosphor-power-supply/chassis_manager.cpp (revision 348168b6ee83b4d1c4d83e47c651e3d51e4f614b)
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