diff options
-rw-r--r-- | control/functor.hpp | 94 |
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 |