From eb639c575a7964b849117cc70b6102f17a2dc32a Mon Sep 17 00:00:00 2001 From: Matthew Barth Date: Fri, 4 Aug 2017 09:43:11 -0500 Subject: Add support to handle InterfacesAdded signals Set speed events can not subscribe to InterfaceAdded signals for properties that are created after fan control initializes the event. Fan control subscribes to property changed signals for all events upon startup where any properties that do not exist are unable to be subscribed to and be notified when their property changes. Therefore, subscribing to the InterfacesAdded signals for properties as well allows any property defined within a set speed event that may not exist upon starting the fan control application get added or updated when the interface it resides on is added. When a subscribed InterfacesAdded signal is caught, the same setProperty handler function will be used to add the property value for the object path, interface, and property name defined to be subscribed to for property change signals. Change-Id: If6fe97288140b83e2e2d735fdf61d52de1ec2e88 Signed-off-by: Matthew Barth --- control/functor.hpp | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/control/functor.hpp b/control/functor.hpp index 2b36445..a5044da 100644 --- a/control/functor.hpp +++ b/control/functor.hpp @@ -117,6 +117,100 @@ auto propertySignal(const char* iface, return PropertyChanged(iface, property, std::forward(handler)); } +/** + * @struct Interface Added + * @brief A match filter functor for Dbus interface added signals + * + * @tparam T - The type of the property value + * @tparam U - The type of the handler + */ +template +struct InterfaceAdded +{ + InterfaceAdded() = delete; + ~InterfaceAdded() = default; + InterfaceAdded(const InterfaceAdded&) = default; + InterfaceAdded& operator=(const InterfaceAdded&) = default; + InterfaceAdded(InterfaceAdded&&) = default; + InterfaceAdded& operator=(InterfaceAdded&&) = default; + InterfaceAdded(const char* path, + const char* iface, + const char* property, + U&& handler) : + _path(path), + _iface(iface), + _property(property), + _handler(std::forward(handler)) { } + + /** @brief Run signal handler function + * + * Extract the property from the InterfacesAdded + * message and run the handler function. + */ + void operator()(sdbusplus::bus::bus&, + sdbusplus::message::message& msg, + Zone& zone) const + { + std::map>> intfProp; + sdbusplus::message::object_path op; + + msg.read(op); + auto objPath = static_cast(op).c_str(); + if (!objPath || strcmp(objPath, _path)) + { + // Object path does not match this handler's path + return; + } + + msg.read(intfProp); + auto itIntf = intfProp.find(_iface); + if (itIntf == intfProp.cend()) + { + // Interface not found on this handler's path + return; + } + auto itProp = itIntf->second.find(_property); + if (itProp == itIntf->second.cend()) + { + // Property not found on this handler's path + return; + } + + _handler(zone, std::forward(itProp->second.template get())); + } + +private: + const char* _path; + const char* _iface; + const char* _property; + U _handler; +}; + +/** + * @brief Used to process a Dbus interface added signal event + * + * @param[in] path - Object path + * @param[in] iface - Object interface + * @param[in] property - Object property + * @param[in] handler - Handler function to perform + * + * @tparam T - The type of the property + * @tparam U - The type of the handler + */ +template +auto objectSignal(const char* path, + const char* iface, + const char* property, + U&& handler) +{ + return InterfaceAdded(path, + iface, + property, + std::forward(handler)); +} + } // namespace control } // namespace fan } // namespace phosphor -- cgit v1.2.1