pseq: Retrieve compatible systems from EM
Retrieve compatible systems value from entity manager using appropriate
D-Bus methods. Will be used to load correct configuration file
containing system rail and pin information.
Signed-off-by: Jim Wright <jlwright@us.ibm.com>
Change-Id: I040b4fcb182f752e5ac1a3c930b53464eebef2da
diff --git a/phosphor-power-sequencer/src/ucd90320_monitor.cpp b/phosphor-power-sequencer/src/ucd90320_monitor.cpp
index 36301b4..cd798d5 100644
--- a/phosphor-power-sequencer/src/ucd90320_monitor.cpp
+++ b/phosphor-power-sequencer/src/ucd90320_monitor.cpp
@@ -16,20 +16,132 @@
#include "ucd90320_monitor.hpp"
-#include <fmt/format.h>
+#include "utility.hpp"
+#include <fmt/format.h>
+#include <fmt/ranges.h>
+
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+
+#include <map>
#include <string>
namespace phosphor::power::sequencer
{
+using namespace phosphor::logging;
+using namespace phosphor::power;
+
+const std::string compatibleInterface =
+ "xyz.openbmc_project.Configuration.IBMCompatibleSystem";
+const std::string compatibleNamesProperty = "Names";
+
UCD90320Monitor::UCD90320Monitor(sdbusplus::bus::bus& bus, std::uint8_t i2cBus,
std::uint16_t i2cAddress) :
PowerSequencerMonitor(),
- bus{bus}, interface {
- fmt::format("/sys/bus/i2c/devices/{}-{:04x}", i2cBus, i2cAddress).c_str(),
- "ucd9000", 0
+ bus{bus}, match{bus,
+ sdbusplus::bus::match::rules::interfacesAdded() +
+ sdbusplus::bus::match::rules::sender(
+ "xyz.openbmc_project.EntityManager"),
+ std::bind(&UCD90320Monitor::interfacesAddedHandler, this,
+ std::placeholders::_1)},
+ pmbusInterface{
+ fmt::format("/sys/bus/i2c/devices/{}-{:04x}", i2cBus, i2cAddress)
+ .c_str(),
+ "ucd9000", 0}
+
+{
+ // Use the compatible system types information, if already available, to
+ // load the configuration file
+ findCompatibleSystemTypes();
}
-{}
+
+void UCD90320Monitor::findCompatibleSystemTypes()
+{
+ try
+ {
+ auto subTree = util::getSubTree(bus, "/xyz/openbmc_project/inventory",
+ compatibleInterface, 0);
+
+ auto objectIt = subTree.cbegin();
+ if (objectIt != subTree.cend())
+ {
+ const auto& objPath = objectIt->first;
+
+ // Get the first service name
+ auto serviceIt = objectIt->second.cbegin();
+ if (serviceIt != objectIt->second.cend())
+ {
+ std::string service = serviceIt->first;
+ if (!service.empty())
+ {
+ std::vector<std::string> compatibleSystemTypes;
+
+ // Get compatible system types property value
+ util::getProperty(compatibleInterface,
+ compatibleNamesProperty, objPath, service,
+ bus, compatibleSystemTypes);
+
+ log<level::DEBUG>(
+ fmt::format("Found compatible systems: {}",
+ compatibleSystemTypes)
+ .c_str());
+ // Use compatible systems information to find config file
+ }
+ }
+ }
+ }
+ catch (const std::exception&)
+ {
+ // Compatible system types information is not available.
+ }
+}
+
+void UCD90320Monitor::interfacesAddedHandler(sdbusplus::message::message& msg)
+{
+ // Verify message is valid
+ if (!msg)
+ {
+ return;
+ }
+
+ try
+ {
+ // Read the dbus message
+ sdbusplus::message::object_path objPath;
+ std::map<std::string,
+ std::map<std::string, std::variant<std::vector<std::string>>>>
+ interfaces;
+ msg.read(objPath, interfaces);
+
+ // Find the compatible interface, if present
+ auto itIntf = interfaces.find(compatibleInterface);
+ if (itIntf != interfaces.cend())
+ {
+ // Find the Names property of the compatible interface, if present
+ auto itProp = itIntf->second.find(compatibleNamesProperty);
+ if (itProp != itIntf->second.cend())
+ {
+ // Get value of Names property
+ const auto& propValue = std::get<0>(itProp->second);
+ if (!propValue.empty())
+ {
+ log<level::INFO>(
+ fmt::format(
+ "InterfacesAdded for compatible systems: {}",
+ propValue)
+ .c_str());
+
+ // Use compatible systems information to find config file
+ }
+ }
+ }
+ }
+ catch (const std::exception&)
+ {
+ // Error trying to read interfacesAdded message.
+ }
+}
} // namespace phosphor::power::sequencer