blob: 710b5dcc0c151c606b30d5ffb3034305cec4650c [file] [log] [blame]
Faisal Awada348168b2025-07-08 11:23:02 -05001#include "config.h"
2
3#include "chassis_manager.hpp"
4
5#include <phosphor-logging/lg2.hpp>
6using namespace phosphor::logging;
7
8namespace phosphor::power::chassis_manager
9{
10using namespace phosphor::power::util;
11constexpr auto managerBusName =
12 "xyz.openbmc_project.Power.MultiChassisPSUMonitor";
13constexpr auto IBMCFFPSInterface =
14 "xyz.openbmc_project.Configuration.IBMCFFPSConnector";
15constexpr auto supportedConfIntf =
16 "xyz.openbmc_project.Configuration.SupportedConfiguration";
17
18ChassisManager::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
45void 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
102phosphor::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
116void ChassisManager::analyze()
117{
118 for (const auto& chassis : listOfChassis)
119 {
120 chassis->analyze();
121 }
122}
123
124void 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