1*38a93a8aSMatthew Barth #pragma once 2*38a93a8aSMatthew Barth 3*38a93a8aSMatthew Barth #include "types.hpp" 4*38a93a8aSMatthew Barth #include <phosphor-logging/log.hpp> 5*38a93a8aSMatthew Barth 6*38a93a8aSMatthew Barth namespace phosphor 7*38a93a8aSMatthew Barth { 8*38a93a8aSMatthew Barth namespace fan 9*38a93a8aSMatthew Barth { 10*38a93a8aSMatthew Barth namespace control 11*38a93a8aSMatthew Barth { 12*38a93a8aSMatthew Barth class Zone; 13*38a93a8aSMatthew Barth 14*38a93a8aSMatthew Barth using namespace phosphor::logging; 15*38a93a8aSMatthew Barth 16*38a93a8aSMatthew Barth /** 17*38a93a8aSMatthew Barth * @brief Create a handler function object 18*38a93a8aSMatthew Barth * 19*38a93a8aSMatthew Barth * @param[in] handler - The handler being created 20*38a93a8aSMatthew Barth * 21*38a93a8aSMatthew Barth * @return - The created handler function object 22*38a93a8aSMatthew Barth */ 23*38a93a8aSMatthew Barth template <typename T> 24*38a93a8aSMatthew Barth auto make_handler(T&& handler) 25*38a93a8aSMatthew Barth { 26*38a93a8aSMatthew Barth return Handler(std::forward<T>(handler)); 27*38a93a8aSMatthew Barth } 28*38a93a8aSMatthew Barth 29*38a93a8aSMatthew Barth /** 30*38a93a8aSMatthew Barth * @struct Property Changed 31*38a93a8aSMatthew Barth * @brief A match filter functor for Dbus property value changed signals 32*38a93a8aSMatthew Barth * 33*38a93a8aSMatthew Barth * @tparam T - The type of the property value 34*38a93a8aSMatthew Barth * @tparam U - The type of the handler 35*38a93a8aSMatthew Barth */ 36*38a93a8aSMatthew Barth template <typename T, typename U> 37*38a93a8aSMatthew Barth struct PropertyChanged 38*38a93a8aSMatthew Barth { 39*38a93a8aSMatthew Barth PropertyChanged() = delete; 40*38a93a8aSMatthew Barth ~PropertyChanged() = default; 41*38a93a8aSMatthew Barth PropertyChanged(const PropertyChanged&) = default; 42*38a93a8aSMatthew Barth PropertyChanged& operator=(const PropertyChanged&) = default; 43*38a93a8aSMatthew Barth PropertyChanged(PropertyChanged&&) = default; 44*38a93a8aSMatthew Barth PropertyChanged& operator=(PropertyChanged&&) = default; 45*38a93a8aSMatthew Barth PropertyChanged(const char* iface, 46*38a93a8aSMatthew Barth const char* property, 47*38a93a8aSMatthew Barth U&& handler) : 48*38a93a8aSMatthew Barth _iface(iface), 49*38a93a8aSMatthew Barth _property(property), 50*38a93a8aSMatthew Barth _handler(std::forward<U>(handler)) { } 51*38a93a8aSMatthew Barth 52*38a93a8aSMatthew Barth /** @brief Run signal handler function 53*38a93a8aSMatthew Barth * 54*38a93a8aSMatthew Barth * Extract the property from the PropertiesChanged 55*38a93a8aSMatthew Barth * message and run the handler function. 56*38a93a8aSMatthew Barth */ 57*38a93a8aSMatthew Barth void operator()(sdbusplus::bus::bus&, 58*38a93a8aSMatthew Barth sdbusplus::message::message& msg, 59*38a93a8aSMatthew Barth Zone& zone) const 60*38a93a8aSMatthew Barth { 61*38a93a8aSMatthew Barth std::map<std::string, sdbusplus::message::variant<T>> properties; 62*38a93a8aSMatthew Barth const char* iface = nullptr; 63*38a93a8aSMatthew Barth 64*38a93a8aSMatthew Barth msg.read(iface); 65*38a93a8aSMatthew Barth if (!iface || strcmp(iface, _iface)) 66*38a93a8aSMatthew Barth { 67*38a93a8aSMatthew Barth return; 68*38a93a8aSMatthew Barth } 69*38a93a8aSMatthew Barth 70*38a93a8aSMatthew Barth msg.read(properties); 71*38a93a8aSMatthew Barth auto it = properties.find(_property); 72*38a93a8aSMatthew Barth if (it == properties.cend()) 73*38a93a8aSMatthew Barth { 74*38a93a8aSMatthew Barth log<level::ERR>("Unable to find property on interface", 75*38a93a8aSMatthew Barth entry("PROPERTY=%s", _property), 76*38a93a8aSMatthew Barth entry("INTERFACE=%s", _iface)); 77*38a93a8aSMatthew Barth return; 78*38a93a8aSMatthew Barth } 79*38a93a8aSMatthew Barth 80*38a93a8aSMatthew Barth _handler(zone, std::forward<T>(it->second.template get<T>())); 81*38a93a8aSMatthew Barth } 82*38a93a8aSMatthew Barth 83*38a93a8aSMatthew Barth private: 84*38a93a8aSMatthew Barth const char* _iface; 85*38a93a8aSMatthew Barth const char* _property; 86*38a93a8aSMatthew Barth U _handler; 87*38a93a8aSMatthew Barth }; 88*38a93a8aSMatthew Barth 89*38a93a8aSMatthew Barth /** 90*38a93a8aSMatthew Barth * @brief Used to process a Dbus property changed signal event 91*38a93a8aSMatthew Barth * 92*38a93a8aSMatthew Barth * @param[in] iface - Sensor value interface 93*38a93a8aSMatthew Barth * @param[in] property - Sensor value property 94*38a93a8aSMatthew Barth * @param[in] handler - Handler function to perform 95*38a93a8aSMatthew Barth * 96*38a93a8aSMatthew Barth * @tparam T - The type of the property 97*38a93a8aSMatthew Barth * @tparam U - The type of the handler 98*38a93a8aSMatthew Barth */ 99*38a93a8aSMatthew Barth template <typename T, typename U> 100*38a93a8aSMatthew Barth auto propertySignal(const char* iface, 101*38a93a8aSMatthew Barth const char* property, 102*38a93a8aSMatthew Barth U&& handler) 103*38a93a8aSMatthew Barth { 104*38a93a8aSMatthew Barth return PropertyChanged<T, U>(iface, property, std::forward<U>(handler)); 105*38a93a8aSMatthew Barth } 106*38a93a8aSMatthew Barth 107*38a93a8aSMatthew Barth } // namespace control 108*38a93a8aSMatthew Barth } // namespace fan 109*38a93a8aSMatthew Barth } // namespace phosphor 110