138a93a8aSMatthew Barth #pragma once 238a93a8aSMatthew Barth 338a93a8aSMatthew Barth #include "types.hpp" 4336f18a5SMatthew Barth #include "sdbusplus.hpp" 538a93a8aSMatthew Barth #include <phosphor-logging/log.hpp> 638a93a8aSMatthew Barth 738a93a8aSMatthew Barth namespace phosphor 838a93a8aSMatthew Barth { 938a93a8aSMatthew Barth namespace fan 1038a93a8aSMatthew Barth { 1138a93a8aSMatthew Barth namespace control 1238a93a8aSMatthew Barth { 1338a93a8aSMatthew Barth class Zone; 1438a93a8aSMatthew Barth 15336f18a5SMatthew Barth using namespace phosphor::fan; 1638a93a8aSMatthew Barth using namespace phosphor::logging; 17336f18a5SMatthew Barth using InternalFailure = sdbusplus::xyz::openbmc_project::Common:: 18336f18a5SMatthew Barth Error::InternalFailure; 1938a93a8aSMatthew Barth 2038a93a8aSMatthew Barth /** 2138a93a8aSMatthew Barth * @brief Create a handler function object 2238a93a8aSMatthew Barth * 2338a93a8aSMatthew Barth * @param[in] handler - The handler being created 2438a93a8aSMatthew Barth * 2538a93a8aSMatthew Barth * @return - The created handler function object 2638a93a8aSMatthew Barth */ 2738a93a8aSMatthew Barth template <typename T> 2838a93a8aSMatthew Barth auto make_handler(T&& handler) 2938a93a8aSMatthew Barth { 3038a93a8aSMatthew Barth return Handler(std::forward<T>(handler)); 3138a93a8aSMatthew Barth } 3238a93a8aSMatthew Barth 3338a93a8aSMatthew Barth /** 3417d1fe23SMatthew Barth * @brief Create an action function object 3517d1fe23SMatthew Barth * 3617d1fe23SMatthew Barth * @param[in] action - The action being created 3717d1fe23SMatthew Barth * 3817d1fe23SMatthew Barth * @return - The created action function object 3917d1fe23SMatthew Barth */ 4017d1fe23SMatthew Barth template <typename T> 4117d1fe23SMatthew Barth auto make_action(T&& action) 4217d1fe23SMatthew Barth { 4317d1fe23SMatthew Barth return Action(std::forward<T>(action)); 4417d1fe23SMatthew Barth } 4517d1fe23SMatthew Barth 4617d1fe23SMatthew Barth /** 4738a93a8aSMatthew Barth * @struct Property Changed 4838a93a8aSMatthew Barth * @brief A match filter functor for Dbus property value changed signals 4938a93a8aSMatthew Barth * 5038a93a8aSMatthew Barth * @tparam T - The type of the property value 5138a93a8aSMatthew Barth * @tparam U - The type of the handler 5238a93a8aSMatthew Barth */ 5338a93a8aSMatthew Barth template <typename T, typename U> 5438a93a8aSMatthew Barth struct PropertyChanged 5538a93a8aSMatthew Barth { 5638a93a8aSMatthew Barth PropertyChanged() = delete; 5738a93a8aSMatthew Barth ~PropertyChanged() = default; 5838a93a8aSMatthew Barth PropertyChanged(const PropertyChanged&) = default; 5938a93a8aSMatthew Barth PropertyChanged& operator=(const PropertyChanged&) = default; 6038a93a8aSMatthew Barth PropertyChanged(PropertyChanged&&) = default; 6138a93a8aSMatthew Barth PropertyChanged& operator=(PropertyChanged&&) = default; 62336f18a5SMatthew Barth PropertyChanged(const char* path, 63336f18a5SMatthew Barth const char* iface, 6438a93a8aSMatthew Barth const char* property, 6538a93a8aSMatthew Barth U&& handler) : 66336f18a5SMatthew Barth _path(path), 6738a93a8aSMatthew Barth _iface(iface), 6838a93a8aSMatthew Barth _property(property), 6938a93a8aSMatthew Barth _handler(std::forward<U>(handler)) { } 7038a93a8aSMatthew Barth 7138a93a8aSMatthew Barth /** @brief Run signal handler function 7238a93a8aSMatthew Barth * 7338a93a8aSMatthew Barth * Extract the property from the PropertiesChanged 74336f18a5SMatthew Barth * message (or read the property when the message is null) 75336f18a5SMatthew Barth * and run the handler function. 7638a93a8aSMatthew Barth */ 77336f18a5SMatthew Barth void operator()(sdbusplus::bus::bus& bus, 7838a93a8aSMatthew Barth sdbusplus::message::message& msg, 7938a93a8aSMatthew Barth Zone& zone) const 8038a93a8aSMatthew Barth { 81336f18a5SMatthew Barth if (msg) 82336f18a5SMatthew Barth { 8338a93a8aSMatthew Barth std::map<std::string, sdbusplus::message::variant<T>> properties; 8438a93a8aSMatthew Barth const char* iface = nullptr; 8538a93a8aSMatthew Barth 8638a93a8aSMatthew Barth msg.read(iface); 8738a93a8aSMatthew Barth if (!iface || strcmp(iface, _iface)) 8838a93a8aSMatthew Barth { 8938a93a8aSMatthew Barth return; 9038a93a8aSMatthew Barth } 9138a93a8aSMatthew Barth 9238a93a8aSMatthew Barth msg.read(properties); 9338a93a8aSMatthew Barth auto it = properties.find(_property); 9438a93a8aSMatthew Barth if (it == properties.cend()) 9538a93a8aSMatthew Barth { 9638a93a8aSMatthew Barth log<level::ERR>("Unable to find property on interface", 9738a93a8aSMatthew Barth entry("PROPERTY=%s", _property), 9838a93a8aSMatthew Barth entry("INTERFACE=%s", _iface)); 9938a93a8aSMatthew Barth return; 10038a93a8aSMatthew Barth } 10138a93a8aSMatthew Barth 10238a93a8aSMatthew Barth _handler(zone, std::forward<T>(it->second.template get<T>())); 10338a93a8aSMatthew Barth } 104336f18a5SMatthew Barth else 105336f18a5SMatthew Barth { 106336f18a5SMatthew Barth try 107336f18a5SMatthew Barth { 108336f18a5SMatthew Barth auto val = util::SDBusPlus::getProperty<T>(bus, 109336f18a5SMatthew Barth _path, 110336f18a5SMatthew Barth _iface, 111336f18a5SMatthew Barth _property); 112336f18a5SMatthew Barth _handler(zone, std::forward<T>(val)); 113336f18a5SMatthew Barth } 114336f18a5SMatthew Barth catch (const InternalFailure& ife) 115336f18a5SMatthew Barth { 116336f18a5SMatthew Barth // Property will not be used unless a property changed 117336f18a5SMatthew Barth // signal message is received for this property. 118336f18a5SMatthew Barth log<level::INFO>( 119336f18a5SMatthew Barth "Property not used, unless PropertyChanged signal received", 120336f18a5SMatthew Barth entry("PATH=%s", _path), 121336f18a5SMatthew Barth entry("INTERFACE=%s", _iface), 122336f18a5SMatthew Barth entry("PROPERTY=%s", _property)); 123336f18a5SMatthew Barth } 124336f18a5SMatthew Barth } 125336f18a5SMatthew Barth } 12638a93a8aSMatthew Barth 12738a93a8aSMatthew Barth private: 128336f18a5SMatthew Barth const char* _path; 12938a93a8aSMatthew Barth const char* _iface; 13038a93a8aSMatthew Barth const char* _property; 13138a93a8aSMatthew Barth U _handler; 13238a93a8aSMatthew Barth }; 13338a93a8aSMatthew Barth 13438a93a8aSMatthew Barth /** 13538a93a8aSMatthew Barth * @brief Used to process a Dbus property changed signal event 13638a93a8aSMatthew Barth * 137336f18a5SMatthew Barth * @param[in] path - Object path 138336f18a5SMatthew Barth * @param[in] iface - Object interface 139336f18a5SMatthew Barth * @param[in] property - Object property 14038a93a8aSMatthew Barth * @param[in] handler - Handler function to perform 14138a93a8aSMatthew Barth * 14238a93a8aSMatthew Barth * @tparam T - The type of the property 14338a93a8aSMatthew Barth * @tparam U - The type of the handler 14438a93a8aSMatthew Barth */ 14538a93a8aSMatthew Barth template <typename T, typename U> 146336f18a5SMatthew Barth auto propertySignal(const char* path, 147336f18a5SMatthew Barth const char* iface, 14838a93a8aSMatthew Barth const char* property, 14938a93a8aSMatthew Barth U&& handler) 15038a93a8aSMatthew Barth { 151336f18a5SMatthew Barth return PropertyChanged<T, U>(path, 152336f18a5SMatthew Barth iface, 153336f18a5SMatthew Barth property, 154336f18a5SMatthew Barth std::forward<U>(handler)); 15538a93a8aSMatthew Barth } 15638a93a8aSMatthew Barth 157eb639c57SMatthew Barth /** 158eb639c57SMatthew Barth * @struct Interface Added 159eb639c57SMatthew Barth * @brief A match filter functor for Dbus interface added signals 160eb639c57SMatthew Barth * 161eb639c57SMatthew Barth * @tparam T - The type of the property value 162eb639c57SMatthew Barth * @tparam U - The type of the handler 163eb639c57SMatthew Barth */ 164eb639c57SMatthew Barth template <typename T, typename U> 165eb639c57SMatthew Barth struct InterfaceAdded 166eb639c57SMatthew Barth { 167eb639c57SMatthew Barth InterfaceAdded() = delete; 168eb639c57SMatthew Barth ~InterfaceAdded() = default; 169eb639c57SMatthew Barth InterfaceAdded(const InterfaceAdded&) = default; 170eb639c57SMatthew Barth InterfaceAdded& operator=(const InterfaceAdded&) = default; 171eb639c57SMatthew Barth InterfaceAdded(InterfaceAdded&&) = default; 172eb639c57SMatthew Barth InterfaceAdded& operator=(InterfaceAdded&&) = default; 173eb639c57SMatthew Barth InterfaceAdded(const char* path, 174eb639c57SMatthew Barth const char* iface, 175eb639c57SMatthew Barth const char* property, 176eb639c57SMatthew Barth U&& handler) : 177eb639c57SMatthew Barth _path(path), 178eb639c57SMatthew Barth _iface(iface), 179eb639c57SMatthew Barth _property(property), 180eb639c57SMatthew Barth _handler(std::forward<U>(handler)) { } 181eb639c57SMatthew Barth 182eb639c57SMatthew Barth /** @brief Run signal handler function 183eb639c57SMatthew Barth * 184eb639c57SMatthew Barth * Extract the property from the InterfacesAdded 185eb639c57SMatthew Barth * message and run the handler function. 186eb639c57SMatthew Barth */ 187eb639c57SMatthew Barth void operator()(sdbusplus::bus::bus&, 188eb639c57SMatthew Barth sdbusplus::message::message& msg, 189eb639c57SMatthew Barth Zone& zone) const 190eb639c57SMatthew Barth { 191336f18a5SMatthew Barth if (msg) 192336f18a5SMatthew Barth { 193eb639c57SMatthew Barth std::map<std::string, 194eb639c57SMatthew Barth std::map<std::string, 195eb639c57SMatthew Barth sdbusplus::message::variant<T>>> intfProp; 196eb639c57SMatthew Barth sdbusplus::message::object_path op; 197eb639c57SMatthew Barth 198eb639c57SMatthew Barth msg.read(op); 199eb639c57SMatthew Barth auto objPath = static_cast<const std::string&>(op).c_str(); 200eb639c57SMatthew Barth if (!objPath || strcmp(objPath, _path)) 201eb639c57SMatthew Barth { 202eb639c57SMatthew Barth // Object path does not match this handler's path 203eb639c57SMatthew Barth return; 204eb639c57SMatthew Barth } 205eb639c57SMatthew Barth 206eb639c57SMatthew Barth msg.read(intfProp); 207eb639c57SMatthew Barth auto itIntf = intfProp.find(_iface); 208eb639c57SMatthew Barth if (itIntf == intfProp.cend()) 209eb639c57SMatthew Barth { 210eb639c57SMatthew Barth // Interface not found on this handler's path 211eb639c57SMatthew Barth return; 212eb639c57SMatthew Barth } 213eb639c57SMatthew Barth auto itProp = itIntf->second.find(_property); 214eb639c57SMatthew Barth if (itProp == itIntf->second.cend()) 215eb639c57SMatthew Barth { 216eb639c57SMatthew Barth // Property not found on this handler's path 217eb639c57SMatthew Barth return; 218eb639c57SMatthew Barth } 219eb639c57SMatthew Barth 220eb639c57SMatthew Barth _handler(zone, std::forward<T>(itProp->second.template get<T>())); 221eb639c57SMatthew Barth } 222336f18a5SMatthew Barth } 223eb639c57SMatthew Barth 224eb639c57SMatthew Barth private: 225eb639c57SMatthew Barth const char* _path; 226eb639c57SMatthew Barth const char* _iface; 227eb639c57SMatthew Barth const char* _property; 228eb639c57SMatthew Barth U _handler; 229eb639c57SMatthew Barth }; 230eb639c57SMatthew Barth 231eb639c57SMatthew Barth /** 232eb639c57SMatthew Barth * @brief Used to process a Dbus interface added signal event 233eb639c57SMatthew Barth * 234eb639c57SMatthew Barth * @param[in] path - Object path 235eb639c57SMatthew Barth * @param[in] iface - Object interface 236eb639c57SMatthew Barth * @param[in] property - Object property 237eb639c57SMatthew Barth * @param[in] handler - Handler function to perform 238eb639c57SMatthew Barth * 239eb639c57SMatthew Barth * @tparam T - The type of the property 240eb639c57SMatthew Barth * @tparam U - The type of the handler 241eb639c57SMatthew Barth */ 242eb639c57SMatthew Barth template <typename T, typename U> 243eb639c57SMatthew Barth auto objectSignal(const char* path, 244eb639c57SMatthew Barth const char* iface, 245eb639c57SMatthew Barth const char* property, 246eb639c57SMatthew Barth U&& handler) 247eb639c57SMatthew Barth { 248eb639c57SMatthew Barth return InterfaceAdded<T, U>(path, 249eb639c57SMatthew Barth iface, 250eb639c57SMatthew Barth property, 251eb639c57SMatthew Barth std::forward<U>(handler)); 252eb639c57SMatthew Barth } 253eb639c57SMatthew Barth 254*8fa02dabSMatthew Barth /** 255*8fa02dabSMatthew Barth * @struct Name Owner Changed 256*8fa02dabSMatthew Barth * @brief A match filter functor for Dbus name owner changed signals 257*8fa02dabSMatthew Barth * 258*8fa02dabSMatthew Barth * @tparam U - The type of the handler 259*8fa02dabSMatthew Barth */ 260*8fa02dabSMatthew Barth template <typename U> 261*8fa02dabSMatthew Barth struct NameOwnerChanged 262*8fa02dabSMatthew Barth { 263*8fa02dabSMatthew Barth NameOwnerChanged() = delete; 264*8fa02dabSMatthew Barth ~NameOwnerChanged() = default; 265*8fa02dabSMatthew Barth NameOwnerChanged(const NameOwnerChanged&) = default; 266*8fa02dabSMatthew Barth NameOwnerChanged& operator=(const NameOwnerChanged&) = default; 267*8fa02dabSMatthew Barth NameOwnerChanged(NameOwnerChanged&&) = default; 268*8fa02dabSMatthew Barth NameOwnerChanged& operator=(NameOwnerChanged&&) = default; 269*8fa02dabSMatthew Barth NameOwnerChanged(const char* path, 270*8fa02dabSMatthew Barth const char* iface, 271*8fa02dabSMatthew Barth U&& handler) : 272*8fa02dabSMatthew Barth _path(path), 273*8fa02dabSMatthew Barth _iface(iface), 274*8fa02dabSMatthew Barth _handler(std::forward<U>(handler)) { } 275*8fa02dabSMatthew Barth 276*8fa02dabSMatthew Barth /** @brief Run signal handler function 277*8fa02dabSMatthew Barth * 278*8fa02dabSMatthew Barth * Extract the name owner from the NameOwnerChanged 279*8fa02dabSMatthew Barth * message (or read the name owner when the message is null) 280*8fa02dabSMatthew Barth * and run the handler function. 281*8fa02dabSMatthew Barth */ 282*8fa02dabSMatthew Barth void operator()(sdbusplus::bus::bus& bus, 283*8fa02dabSMatthew Barth sdbusplus::message::message& msg, 284*8fa02dabSMatthew Barth Zone& zone) const 285*8fa02dabSMatthew Barth { 286*8fa02dabSMatthew Barth if (msg) 287*8fa02dabSMatthew Barth { 288*8fa02dabSMatthew Barth // TODO Handle NameOwnerChanged signals 289*8fa02dabSMatthew Barth } 290*8fa02dabSMatthew Barth else 291*8fa02dabSMatthew Barth { 292*8fa02dabSMatthew Barth // TODO Initialize NameOwnerChanged data store with service names 293*8fa02dabSMatthew Barth } 294*8fa02dabSMatthew Barth } 295*8fa02dabSMatthew Barth 296*8fa02dabSMatthew Barth private: 297*8fa02dabSMatthew Barth const char* _path; 298*8fa02dabSMatthew Barth const char* _iface; 299*8fa02dabSMatthew Barth U _handler; 300*8fa02dabSMatthew Barth }; 301*8fa02dabSMatthew Barth 302*8fa02dabSMatthew Barth /** 303*8fa02dabSMatthew Barth * @brief Used to process a Dbus name owner changed signal event 304*8fa02dabSMatthew Barth * 305*8fa02dabSMatthew Barth * @param[in] path - Object path 306*8fa02dabSMatthew Barth * @param[in] iface - Object interface 307*8fa02dabSMatthew Barth * @param[in] handler - Handler function to perform 308*8fa02dabSMatthew Barth * 309*8fa02dabSMatthew Barth * @tparam U - The type of the handler 310*8fa02dabSMatthew Barth * 311*8fa02dabSMatthew Barth * @return - The NameOwnerChanged signal struct 312*8fa02dabSMatthew Barth */ 313*8fa02dabSMatthew Barth template <typename U> 314*8fa02dabSMatthew Barth auto ownerSignal(const char* path, 315*8fa02dabSMatthew Barth const char* iface, 316*8fa02dabSMatthew Barth U&& handler) 317*8fa02dabSMatthew Barth { 318*8fa02dabSMatthew Barth return NameOwnerChanged<U>(path, 319*8fa02dabSMatthew Barth iface, 320*8fa02dabSMatthew Barth std::forward<U>(handler)); 321*8fa02dabSMatthew Barth } 322*8fa02dabSMatthew Barth 32338a93a8aSMatthew Barth } // namespace control 32438a93a8aSMatthew Barth } // namespace fan 32538a93a8aSMatthew Barth } // namespace phosphor 326