138a93a8aSMatthew Barth #pragma once 238a93a8aSMatthew Barth 338a93a8aSMatthew Barth #include "types.hpp" 438a93a8aSMatthew Barth #include <phosphor-logging/log.hpp> 538a93a8aSMatthew Barth 638a93a8aSMatthew Barth namespace phosphor 738a93a8aSMatthew Barth { 838a93a8aSMatthew Barth namespace fan 938a93a8aSMatthew Barth { 1038a93a8aSMatthew Barth namespace control 1138a93a8aSMatthew Barth { 1238a93a8aSMatthew Barth class Zone; 1338a93a8aSMatthew Barth 1438a93a8aSMatthew Barth using namespace phosphor::logging; 1538a93a8aSMatthew Barth 1638a93a8aSMatthew Barth /** 1738a93a8aSMatthew Barth * @brief Create a handler function object 1838a93a8aSMatthew Barth * 1938a93a8aSMatthew Barth * @param[in] handler - The handler being created 2038a93a8aSMatthew Barth * 2138a93a8aSMatthew Barth * @return - The created handler function object 2238a93a8aSMatthew Barth */ 2338a93a8aSMatthew Barth template <typename T> 2438a93a8aSMatthew Barth auto make_handler(T&& handler) 2538a93a8aSMatthew Barth { 2638a93a8aSMatthew Barth return Handler(std::forward<T>(handler)); 2738a93a8aSMatthew Barth } 2838a93a8aSMatthew Barth 2938a93a8aSMatthew Barth /** 3017d1fe23SMatthew Barth * @brief Create an action function object 3117d1fe23SMatthew Barth * 3217d1fe23SMatthew Barth * @param[in] action - The action being created 3317d1fe23SMatthew Barth * 3417d1fe23SMatthew Barth * @return - The created action function object 3517d1fe23SMatthew Barth */ 3617d1fe23SMatthew Barth template <typename T> 3717d1fe23SMatthew Barth auto make_action(T&& action) 3817d1fe23SMatthew Barth { 3917d1fe23SMatthew Barth return Action(std::forward<T>(action)); 4017d1fe23SMatthew Barth } 4117d1fe23SMatthew Barth 4217d1fe23SMatthew Barth /** 4338a93a8aSMatthew Barth * @struct Property Changed 4438a93a8aSMatthew Barth * @brief A match filter functor for Dbus property value changed signals 4538a93a8aSMatthew Barth * 4638a93a8aSMatthew Barth * @tparam T - The type of the property value 4738a93a8aSMatthew Barth * @tparam U - The type of the handler 4838a93a8aSMatthew Barth */ 4938a93a8aSMatthew Barth template <typename T, typename U> 5038a93a8aSMatthew Barth struct PropertyChanged 5138a93a8aSMatthew Barth { 5238a93a8aSMatthew Barth PropertyChanged() = delete; 5338a93a8aSMatthew Barth ~PropertyChanged() = default; 5438a93a8aSMatthew Barth PropertyChanged(const PropertyChanged&) = default; 5538a93a8aSMatthew Barth PropertyChanged& operator=(const PropertyChanged&) = default; 5638a93a8aSMatthew Barth PropertyChanged(PropertyChanged&&) = default; 5738a93a8aSMatthew Barth PropertyChanged& operator=(PropertyChanged&&) = default; 5838a93a8aSMatthew Barth PropertyChanged(const char* iface, 5938a93a8aSMatthew Barth const char* property, 6038a93a8aSMatthew Barth U&& handler) : 6138a93a8aSMatthew Barth _iface(iface), 6238a93a8aSMatthew Barth _property(property), 6338a93a8aSMatthew Barth _handler(std::forward<U>(handler)) { } 6438a93a8aSMatthew Barth 6538a93a8aSMatthew Barth /** @brief Run signal handler function 6638a93a8aSMatthew Barth * 6738a93a8aSMatthew Barth * Extract the property from the PropertiesChanged 6838a93a8aSMatthew Barth * message and run the handler function. 6938a93a8aSMatthew Barth */ 7038a93a8aSMatthew Barth void operator()(sdbusplus::bus::bus&, 7138a93a8aSMatthew Barth sdbusplus::message::message& msg, 7238a93a8aSMatthew Barth Zone& zone) const 7338a93a8aSMatthew Barth { 7438a93a8aSMatthew Barth std::map<std::string, sdbusplus::message::variant<T>> properties; 7538a93a8aSMatthew Barth const char* iface = nullptr; 7638a93a8aSMatthew Barth 7738a93a8aSMatthew Barth msg.read(iface); 7838a93a8aSMatthew Barth if (!iface || strcmp(iface, _iface)) 7938a93a8aSMatthew Barth { 8038a93a8aSMatthew Barth return; 8138a93a8aSMatthew Barth } 8238a93a8aSMatthew Barth 8338a93a8aSMatthew Barth msg.read(properties); 8438a93a8aSMatthew Barth auto it = properties.find(_property); 8538a93a8aSMatthew Barth if (it == properties.cend()) 8638a93a8aSMatthew Barth { 8738a93a8aSMatthew Barth log<level::ERR>("Unable to find property on interface", 8838a93a8aSMatthew Barth entry("PROPERTY=%s", _property), 8938a93a8aSMatthew Barth entry("INTERFACE=%s", _iface)); 9038a93a8aSMatthew Barth return; 9138a93a8aSMatthew Barth } 9238a93a8aSMatthew Barth 9338a93a8aSMatthew Barth _handler(zone, std::forward<T>(it->second.template get<T>())); 9438a93a8aSMatthew Barth } 9538a93a8aSMatthew Barth 9638a93a8aSMatthew Barth private: 9738a93a8aSMatthew Barth const char* _iface; 9838a93a8aSMatthew Barth const char* _property; 9938a93a8aSMatthew Barth U _handler; 10038a93a8aSMatthew Barth }; 10138a93a8aSMatthew Barth 10238a93a8aSMatthew Barth /** 10338a93a8aSMatthew Barth * @brief Used to process a Dbus property changed signal event 10438a93a8aSMatthew Barth * 10538a93a8aSMatthew Barth * @param[in] iface - Sensor value interface 10638a93a8aSMatthew Barth * @param[in] property - Sensor value property 10738a93a8aSMatthew Barth * @param[in] handler - Handler function to perform 10838a93a8aSMatthew Barth * 10938a93a8aSMatthew Barth * @tparam T - The type of the property 11038a93a8aSMatthew Barth * @tparam U - The type of the handler 11138a93a8aSMatthew Barth */ 11238a93a8aSMatthew Barth template <typename T, typename U> 11338a93a8aSMatthew Barth auto propertySignal(const char* iface, 11438a93a8aSMatthew Barth const char* property, 11538a93a8aSMatthew Barth U&& handler) 11638a93a8aSMatthew Barth { 11738a93a8aSMatthew Barth return PropertyChanged<T, U>(iface, property, std::forward<U>(handler)); 11838a93a8aSMatthew Barth } 11938a93a8aSMatthew Barth 120*eb639c57SMatthew Barth /** 121*eb639c57SMatthew Barth * @struct Interface Added 122*eb639c57SMatthew Barth * @brief A match filter functor for Dbus interface added signals 123*eb639c57SMatthew Barth * 124*eb639c57SMatthew Barth * @tparam T - The type of the property value 125*eb639c57SMatthew Barth * @tparam U - The type of the handler 126*eb639c57SMatthew Barth */ 127*eb639c57SMatthew Barth template <typename T, typename U> 128*eb639c57SMatthew Barth struct InterfaceAdded 129*eb639c57SMatthew Barth { 130*eb639c57SMatthew Barth InterfaceAdded() = delete; 131*eb639c57SMatthew Barth ~InterfaceAdded() = default; 132*eb639c57SMatthew Barth InterfaceAdded(const InterfaceAdded&) = default; 133*eb639c57SMatthew Barth InterfaceAdded& operator=(const InterfaceAdded&) = default; 134*eb639c57SMatthew Barth InterfaceAdded(InterfaceAdded&&) = default; 135*eb639c57SMatthew Barth InterfaceAdded& operator=(InterfaceAdded&&) = default; 136*eb639c57SMatthew Barth InterfaceAdded(const char* path, 137*eb639c57SMatthew Barth const char* iface, 138*eb639c57SMatthew Barth const char* property, 139*eb639c57SMatthew Barth U&& handler) : 140*eb639c57SMatthew Barth _path(path), 141*eb639c57SMatthew Barth _iface(iface), 142*eb639c57SMatthew Barth _property(property), 143*eb639c57SMatthew Barth _handler(std::forward<U>(handler)) { } 144*eb639c57SMatthew Barth 145*eb639c57SMatthew Barth /** @brief Run signal handler function 146*eb639c57SMatthew Barth * 147*eb639c57SMatthew Barth * Extract the property from the InterfacesAdded 148*eb639c57SMatthew Barth * message and run the handler function. 149*eb639c57SMatthew Barth */ 150*eb639c57SMatthew Barth void operator()(sdbusplus::bus::bus&, 151*eb639c57SMatthew Barth sdbusplus::message::message& msg, 152*eb639c57SMatthew Barth Zone& zone) const 153*eb639c57SMatthew Barth { 154*eb639c57SMatthew Barth std::map<std::string, 155*eb639c57SMatthew Barth std::map<std::string, 156*eb639c57SMatthew Barth sdbusplus::message::variant<T>>> intfProp; 157*eb639c57SMatthew Barth sdbusplus::message::object_path op; 158*eb639c57SMatthew Barth 159*eb639c57SMatthew Barth msg.read(op); 160*eb639c57SMatthew Barth auto objPath = static_cast<const std::string&>(op).c_str(); 161*eb639c57SMatthew Barth if (!objPath || strcmp(objPath, _path)) 162*eb639c57SMatthew Barth { 163*eb639c57SMatthew Barth // Object path does not match this handler's path 164*eb639c57SMatthew Barth return; 165*eb639c57SMatthew Barth } 166*eb639c57SMatthew Barth 167*eb639c57SMatthew Barth msg.read(intfProp); 168*eb639c57SMatthew Barth auto itIntf = intfProp.find(_iface); 169*eb639c57SMatthew Barth if (itIntf == intfProp.cend()) 170*eb639c57SMatthew Barth { 171*eb639c57SMatthew Barth // Interface not found on this handler's path 172*eb639c57SMatthew Barth return; 173*eb639c57SMatthew Barth } 174*eb639c57SMatthew Barth auto itProp = itIntf->second.find(_property); 175*eb639c57SMatthew Barth if (itProp == itIntf->second.cend()) 176*eb639c57SMatthew Barth { 177*eb639c57SMatthew Barth // Property not found on this handler's path 178*eb639c57SMatthew Barth return; 179*eb639c57SMatthew Barth } 180*eb639c57SMatthew Barth 181*eb639c57SMatthew Barth _handler(zone, std::forward<T>(itProp->second.template get<T>())); 182*eb639c57SMatthew Barth } 183*eb639c57SMatthew Barth 184*eb639c57SMatthew Barth private: 185*eb639c57SMatthew Barth const char* _path; 186*eb639c57SMatthew Barth const char* _iface; 187*eb639c57SMatthew Barth const char* _property; 188*eb639c57SMatthew Barth U _handler; 189*eb639c57SMatthew Barth }; 190*eb639c57SMatthew Barth 191*eb639c57SMatthew Barth /** 192*eb639c57SMatthew Barth * @brief Used to process a Dbus interface added signal event 193*eb639c57SMatthew Barth * 194*eb639c57SMatthew Barth * @param[in] path - Object path 195*eb639c57SMatthew Barth * @param[in] iface - Object interface 196*eb639c57SMatthew Barth * @param[in] property - Object property 197*eb639c57SMatthew Barth * @param[in] handler - Handler function to perform 198*eb639c57SMatthew Barth * 199*eb639c57SMatthew Barth * @tparam T - The type of the property 200*eb639c57SMatthew Barth * @tparam U - The type of the handler 201*eb639c57SMatthew Barth */ 202*eb639c57SMatthew Barth template <typename T, typename U> 203*eb639c57SMatthew Barth auto objectSignal(const char* path, 204*eb639c57SMatthew Barth const char* iface, 205*eb639c57SMatthew Barth const char* property, 206*eb639c57SMatthew Barth U&& handler) 207*eb639c57SMatthew Barth { 208*eb639c57SMatthew Barth return InterfaceAdded<T, U>(path, 209*eb639c57SMatthew Barth iface, 210*eb639c57SMatthew Barth property, 211*eb639c57SMatthew Barth std::forward<U>(handler)); 212*eb639c57SMatthew Barth } 213*eb639c57SMatthew Barth 21438a93a8aSMatthew Barth } // namespace control 21538a93a8aSMatthew Barth } // namespace fan 21638a93a8aSMatthew Barth } // namespace phosphor 217