summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--control/functor.hpp7
-rw-r--r--control/zone.cpp35
-rw-r--r--control/zone.hpp65
3 files changed, 99 insertions, 8 deletions
diff --git a/control/functor.hpp b/control/functor.hpp
index b96f650..71607c5 100644
--- a/control/functor.hpp
+++ b/control/functor.hpp
@@ -106,12 +106,7 @@ struct PropertyChanged
{
try
{
- auto service = zone.getService(_path, _iface);
- auto val = util::SDBusPlus::getProperty<T>(bus,
- service,
- _path,
- _iface,
- _property);
+ auto val = zone.getPropertyByName<T>(_path, _iface, _property);
_handler(zone, std::forward<T>(val));
}
catch (const sdbusplus::exception::SdBusError&)
diff --git a/control/zone.cpp b/control/zone.cpp
index bc40b7e..60d2947 100644
--- a/control/zone.cpp
+++ b/control/zone.cpp
@@ -51,6 +51,7 @@ Zone::Zone(Mode mode,
ThermalObject(bus, path.c_str(), true),
_bus(bus),
_path(path),
+ _ifaces({"xyz.openbmc_project.Control.ThermalMode"}),
_fullSpeed(std::get<fullSpeedPos>(def)),
_zoneNum(std::get<zoneNumPos>(def)),
_defFloorSpeed(std::get<floorSpeedPos>(def)),
@@ -316,8 +317,6 @@ void Zone::initEvent(const SetSpeedEvent& event)
for (auto& sig : std::get<signalsPos>(event))
{
- // Initialize the event signal using handler
- std::get<sigHandlerPos>(sig)(_bus, nullMsg, *this);
// Setup signal matches of the property for event
std::unique_ptr<EventData> eventData =
std::make_unique<EventData>(
@@ -326,6 +325,37 @@ void Zone::initEvent(const SetSpeedEvent& event)
std::get<sigHandlerPos>(sig),
std::get<actionsPos>(event)
);
+
+ // When match is empty, handle if zone object member
+ if (std::get<sigMatchPos>(sig).empty())
+ {
+ fs::path path{CONTROL_OBJPATH};
+ path /= std::to_string(_zoneNum);
+
+ // Set event data for each host group member
+ for (auto it = std::get<groupPos>(event).begin();
+ it != std::get<groupPos>(event).end(); ++it)
+ {
+ if (it->first == path.string())
+ {
+ // Group member interface in list owned by zone
+ if (std::find(_ifaces.begin(), _ifaces.end(),
+ std::get<intfPos>(it->second)) != _ifaces.end())
+ {
+ // Store path,interface,property as a managed object
+ _objects[it->first]
+ [std::get<intfPos>(it->second)]
+ [std::get<propPos>(it->second)] =
+ eventData.get();
+ }
+ }
+ }
+ }
+
+ // Initialize the event signal using handler
+ std::get<sigHandlerPos>(sig)(_bus, nullMsg, *this);
+
+ // Subscribe to signal match
std::unique_ptr<sdbusplus::server::match::match> match = nullptr;
if (!std::get<sigMatchPos>(sig).empty())
{
@@ -338,6 +368,7 @@ void Zone::initEvent(const SetSpeedEvent& event)
eventData.get())
);
}
+
_signalEvents.emplace_back(std::move(eventData), std::move(match));
}
// Attach a timer to run the action of an event
diff --git a/control/zone.hpp b/control/zone.hpp
index 73761d0..2633902 100644
--- a/control/zone.hpp
+++ b/control/zone.hpp
@@ -7,6 +7,7 @@
#include <vector>
#include "fan.hpp"
#include "types.hpp"
+#include "sdbusplus.hpp"
#include "xyz/openbmc_project/Control/ThermalMode/server.hpp"
namespace phosphor
@@ -469,6 +470,57 @@ class Zone : public ThermalObject
int32_t depth);
/**
+ * @brief Get a property value from the zone object or the bus when
+ * the property requested is not on the zone object
+ *
+ * @param[in] path - Path of object
+ * @param[in] intf - Object interface
+ * @param[in] prop - Object property
+ *
+ * @return - Property's value
+ */
+ template <typename T>
+ auto getPropertyByName(const std::string& path,
+ const std::string& intf,
+ const std::string& prop)
+ {
+ T value;
+ auto pathIter = _objects.find(path);
+ if (pathIter != _objects.end())
+ {
+ auto intfIter = pathIter->second.find(intf);
+ if (intfIter != pathIter->second.end())
+ {
+ if (intf == "xyz.openbmc_project.Control.ThermalMode")
+ {
+ auto var = ThermalMode::getPropertyByName(prop);
+ // Use visitor to determine if requested property
+ // type(T) is available on this interface and read it
+ std::visit([&value](auto&& val)
+ {
+ using V = std::decay_t<decltype(val)>;
+ if constexpr(std::is_same_v<T, V>)
+ {
+ value = val;
+ }
+ }, var);
+
+ return value;
+ }
+ }
+ }
+
+ auto service = getService(path, intf);
+ value = util::SDBusPlus::getProperty<T>(_bus,
+ service,
+ path,
+ intf,
+ prop);
+
+ return value;
+ };
+
+ /**
* @brief Overridden thermal object's set 'Current' property function
*
* @param[in] value - Value to set 'Current' to
@@ -490,6 +542,11 @@ class Zone : public ThermalObject
const std::string _path;
/**
+ * Zone supported interfaces
+ */
+ const std::vector<std::string> _ifaces;
+
+ /**
* Full speed for the zone
*/
const uint64_t _fullSpeed;
@@ -588,6 +645,14 @@ class Zone : public ThermalObject
PropertyVariantType>>> _properties;
/**
+ * @brief Map of zone objects
+ */
+ std::map<std::string,
+ std::map<std::string,
+ std::map<std::string,
+ EventData*>>> _objects;
+
+ /**
* @brief Map of active fan control allowed by groups
*/
std::map<const Group, bool> _active;
OpenPOWER on IntegriCloud