From 766f8545fd3eb5010f5a262aa398f3a11dcc07d7 Mon Sep 17 00:00:00 2001 From: Matthew Barth Date: Tue, 29 Jan 2019 12:44:13 -0600 Subject: Store and access zone object properties Properties on the zone object require their event data to be stored for retrieval when their value changes, which allows the use of the current event handlers to update the cached value and trigger the event actions. When any event is initialized, any signals where the match string is empty performs a lookup for each group member to determine if they are on the zone object. Each member found to be on the zone object is then stored with the that event's data. Tested: Verified event data is stored for members on the zone object Verified event initialization correctly accesses zone object member's event data Change-Id: Id34f60eb12330428eeb1041de4e9bd1a4a686f21 Signed-off-by: Matthew Barth --- control/functor.hpp | 7 +----- control/zone.cpp | 35 +++++++++++++++++++++++++++-- control/zone.hpp | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 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(bus, - service, - _path, - _iface, - _property); + auto val = zone.getPropertyByName(_path, _iface, _property); _handler(zone, std::forward(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(def)), _zoneNum(std::get(def)), _defFloorSpeed(std::get(def)), @@ -316,8 +317,6 @@ void Zone::initEvent(const SetSpeedEvent& event) for (auto& sig : std::get(event)) { - // Initialize the event signal using handler - std::get(sig)(_bus, nullMsg, *this); // Setup signal matches of the property for event std::unique_ptr eventData = std::make_unique( @@ -326,6 +325,37 @@ void Zone::initEvent(const SetSpeedEvent& event) std::get(sig), std::get(event) ); + + // When match is empty, handle if zone object member + if (std::get(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(event).begin(); + it != std::get(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(it->second)) != _ifaces.end()) + { + // Store path,interface,property as a managed object + _objects[it->first] + [std::get(it->second)] + [std::get(it->second)] = + eventData.get(); + } + } + } + } + + // Initialize the event signal using handler + std::get(sig)(_bus, nullMsg, *this); + + // Subscribe to signal match std::unique_ptr match = nullptr; if (!std::get(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 #include "fan.hpp" #include "types.hpp" +#include "sdbusplus.hpp" #include "xyz/openbmc_project/Control/ThermalMode/server.hpp" namespace phosphor @@ -468,6 +469,57 @@ class Zone : public ThermalObject const std::string& intf, 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 + 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; + if constexpr(std::is_same_v) + { + value = val; + } + }, var); + + return value; + } + } + } + + auto service = getService(path, intf); + value = util::SDBusPlus::getProperty(_bus, + service, + path, + intf, + prop); + + return value; + }; + /** * @brief Overridden thermal object's set 'Current' property function * @@ -489,6 +541,11 @@ class Zone : public ThermalObject */ const std::string _path; + /** + * Zone supported interfaces + */ + const std::vector _ifaces; + /** * Full speed for the zone */ @@ -587,6 +644,14 @@ class Zone : public ThermalObject std::map>> _properties; + /** + * @brief Map of zone objects + */ + std::map>> _objects; + /** * @brief Map of active fan control allowed by groups */ -- cgit v1.2.1