summaryrefslogtreecommitdiffstats
path: root/control/functor.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'control/functor.hpp')
-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