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