summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barth <msbarth@us.ibm.com>2017-08-04 09:43:11 -0500
committerMatthew Barth <msbarth@us.ibm.com>2017-08-07 15:17:16 -0500
commiteb639c575a7964b849117cc70b6102f17a2dc32a (patch)
tree5338ce9ab57507a7f2af2bb0ee923ba8191a5a5a
parentccc7770ecd6b758fcef98ce9e7cd585af3f3c77f (diff)
downloadphosphor-fan-presence-eb639c575a7964b849117cc70b6102f17a2dc32a.tar.gz
phosphor-fan-presence-eb639c575a7964b849117cc70b6102f17a2dc32a.zip
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 <msbarth@us.ibm.com>
-rw-r--r--control/functor.hpp94
1 files changed, 94 insertions, 0 deletions
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<T, U>(iface, property, std::forward<U>(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 <typename T, typename U>
+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<U>(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<std::string,
+ std::map<std::string,
+ sdbusplus::message::variant<T>>> intfProp;
+ sdbusplus::message::object_path op;
+
+ msg.read(op);
+ auto objPath = static_cast<const std::string&>(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<T>(itProp->second.template get<T>()));
+ }
+
+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 <typename T, typename U>
+auto objectSignal(const char* path,
+ const char* iface,
+ const char* property,
+ U&& handler)
+{
+ return InterfaceAdded<T, U>(path,
+ iface,
+ property,
+ std::forward<U>(handler));
+}
+
} // namespace control
} // namespace fan
} // namespace phosphor
OpenPOWER on IntegriCloud