1c1f4798dSBrad Bishop #pragma once 2c1f4798dSBrad Bishop 3a680d1efSPatrick Venture #include "types.hpp" 4a680d1efSPatrick Venture #include "utils.hpp" 5a680d1efSPatrick Venture 6c1f4798dSBrad Bishop #include <memory> 7c1f4798dSBrad Bishop #include <sdbusplus/bus.hpp> 8a680d1efSPatrick Venture #include <utility> 9c1f4798dSBrad Bishop 10c1f4798dSBrad Bishop namespace phosphor 11c1f4798dSBrad Bishop { 12c1f4798dSBrad Bishop namespace inventory 13c1f4798dSBrad Bishop { 14c1f4798dSBrad Bishop namespace manager 15c1f4798dSBrad Bishop { 16c1f4798dSBrad Bishop 17c1f4798dSBrad Bishop class Manager; 18c1f4798dSBrad Bishop 19c1f4798dSBrad Bishop /** @brief make_action 20c1f4798dSBrad Bishop * 21c1f4798dSBrad Bishop * Adapt an action function object. 22c1f4798dSBrad Bishop * 23c1f4798dSBrad Bishop * @param[in] action - The action being adapted. 24c1f4798dSBrad Bishop * @returns - The adapted action. 25c1f4798dSBrad Bishop * 26c1f4798dSBrad Bishop * @tparam T - The type of the action being adapted. 27c1f4798dSBrad Bishop */ 28a680d1efSPatrick Venture template <typename T> 29a680d1efSPatrick Venture auto make_action(T&& action) 30c1f4798dSBrad Bishop { 31c1f4798dSBrad Bishop return Action(std::forward<T>(action)); 32c1f4798dSBrad Bishop } 33c1f4798dSBrad Bishop 34c1f4798dSBrad Bishop /** @brief make_filter 35c1f4798dSBrad Bishop * 36c1f4798dSBrad Bishop * Adapt a filter function object. 37c1f4798dSBrad Bishop * 38c1f4798dSBrad Bishop * @param[in] filter - The filter being adapted. 39c1f4798dSBrad Bishop * @returns - The adapted filter. 40c1f4798dSBrad Bishop * 41c1f4798dSBrad Bishop * @tparam T - The type of the filter being adapted. 42c1f4798dSBrad Bishop */ 43a680d1efSPatrick Venture template <typename T> 44a680d1efSPatrick Venture auto make_filter(T&& filter) 45c1f4798dSBrad Bishop { 46c1f4798dSBrad Bishop return Filter(std::forward<T>(filter)); 47c1f4798dSBrad Bishop } 48c1f4798dSBrad Bishop 49d0f48adcSBrad Bishop /** @brief make_path_condition 50d0f48adcSBrad Bishop * 51d0f48adcSBrad Bishop * Adapt a path_condition function object. 52d0f48adcSBrad Bishop * 53d0f48adcSBrad Bishop * @param[in] filter - The functor being adapted. 54d0f48adcSBrad Bishop * @returns - The adapted functor. 55d0f48adcSBrad Bishop * 56d0f48adcSBrad Bishop * @tparam T - The type of the functor being adapted. 57d0f48adcSBrad Bishop */ 58a680d1efSPatrick Venture template <typename T> 59a680d1efSPatrick Venture auto make_path_condition(T&& condition) 60d0f48adcSBrad Bishop { 61d0f48adcSBrad Bishop return PathCondition(std::forward<T>(condition)); 62d0f48adcSBrad Bishop } 63d0f48adcSBrad Bishop 64f094d442SMatthew Barth /** @brief make_get_property 65f094d442SMatthew Barth * 66f094d442SMatthew Barth * Adapt a get_property function object. 67f094d442SMatthew Barth * 68f094d442SMatthew Barth * @param[in] method - The functor being adapted. 69f094d442SMatthew Barth * @returns - The adapted functor. 70f094d442SMatthew Barth * 71f094d442SMatthew Barth * @tparam T - The return type of the function object. 72f094d442SMatthew Barth * @tparam U - The type of the functor being adapted. 73f094d442SMatthew Barth */ 74f094d442SMatthew Barth template <typename T, typename U> 75f094d442SMatthew Barth auto make_get_property(U&& method) 76f094d442SMatthew Barth { 77f094d442SMatthew Barth return GetProperty<T>(std::forward<U>(method)); 78f094d442SMatthew Barth } 79f094d442SMatthew Barth 80d0f48adcSBrad Bishop template <typename T, typename... Args> 81d0f48adcSBrad Bishop auto callArrayWithStatus(T&& container, Args&&... args) 82d0f48adcSBrad Bishop { 83d0f48adcSBrad Bishop for (auto f : container) 84d0f48adcSBrad Bishop { 85d0f48adcSBrad Bishop if (!f(std::forward<Args>(args)...)) 86d0f48adcSBrad Bishop { 87d0f48adcSBrad Bishop return false; 88d0f48adcSBrad Bishop } 89d0f48adcSBrad Bishop } 90d0f48adcSBrad Bishop return true; 91d0f48adcSBrad Bishop } 92d0f48adcSBrad Bishop 93c1f4798dSBrad Bishop namespace functor 94c1f4798dSBrad Bishop { 95c1f4798dSBrad Bishop 96c1f4798dSBrad Bishop /** @brief Destroy objects action. */ 97615b2a8fSBrad Bishop inline auto destroyObjects(std::vector<const char*>&& paths, 98d0f48adcSBrad Bishop std::vector<PathCondition>&& conditions) 99c1f4798dSBrad Bishop { 100615b2a8fSBrad Bishop return [=](auto& b, auto& m) { 101d0f48adcSBrad Bishop for (const auto& p : paths) 102d0f48adcSBrad Bishop { 103d0f48adcSBrad Bishop if (callArrayWithStatus(conditions, p, b, m)) 104d0f48adcSBrad Bishop { 105d0f48adcSBrad Bishop m.destroyObjects({p}); 106d0f48adcSBrad Bishop } 107d0f48adcSBrad Bishop } 108c1f4798dSBrad Bishop }; 109c1f4798dSBrad Bishop } 110c1f4798dSBrad Bishop 111c1f4798dSBrad Bishop /** @brief Create objects action. */ 112615b2a8fSBrad Bishop inline auto 113615b2a8fSBrad Bishop createObjects(std::map<sdbusplus::message::object_path, Object>&& objs) 114c1f4798dSBrad Bishop { 115615b2a8fSBrad Bishop return [=](auto&, auto& m) { m.createObjects(objs); }; 116c1f4798dSBrad Bishop } 117c1f4798dSBrad Bishop 118c1f4798dSBrad Bishop /** @brief Set a property action. 119c1f4798dSBrad Bishop * 120c1f4798dSBrad Bishop * Invoke the requested method with a reference to the requested 121c1f4798dSBrad Bishop * sdbusplus server binding interface as a parameter. 122c1f4798dSBrad Bishop * 123c1f4798dSBrad Bishop * @tparam T - The sdbusplus server binding interface type. 124c1f4798dSBrad Bishop * @tparam U - The type of the sdbusplus server binding member 125c1f4798dSBrad Bishop * function that sets the property. 126c1f4798dSBrad Bishop * @tparam V - The property value type. 127c1f4798dSBrad Bishop * 128c1f4798dSBrad Bishop * @param[in] paths - The DBus paths on which the property should 129c1f4798dSBrad Bishop * be set. 130c1f4798dSBrad Bishop * @param[in] iface - The DBus interface hosting the property. 131c1f4798dSBrad Bishop * @param[in] member - Pointer to sdbusplus server binding member. 132c1f4798dSBrad Bishop * @param[in] value - The value the property should be set to. 133c1f4798dSBrad Bishop * 134c1f4798dSBrad Bishop * @returns - A function object that sets the requested property 135c1f4798dSBrad Bishop * to the requested value. 136c1f4798dSBrad Bishop */ 137c1f4798dSBrad Bishop template <typename T, typename U, typename V> 138615b2a8fSBrad Bishop auto setProperty(std::vector<const char*>&& paths, 139615b2a8fSBrad Bishop std::vector<PathCondition>&& conditions, const char* iface, 140615b2a8fSBrad Bishop U&& member, V&& value) 141c1f4798dSBrad Bishop { 142c1f4798dSBrad Bishop // The manager is the only parameter passed to actions. 143c1f4798dSBrad Bishop // Bind the path, interface, interface member function pointer, 144c1f4798dSBrad Bishop // and value to a lambda. When it is called, forward the 145c1f4798dSBrad Bishop // path, interface and value on to the manager member function. 146a680d1efSPatrick Venture return [paths, conditions = conditions, iface, member, 147a680d1efSPatrick Venture value = std::forward<V>(value)](auto& b, auto& m) { 148c1f4798dSBrad Bishop for (auto p : paths) 149c1f4798dSBrad Bishop { 150d0f48adcSBrad Bishop if (callArrayWithStatus(conditions, p, b, m)) 151d0f48adcSBrad Bishop { 152615b2a8fSBrad Bishop m.template invokeMethod<T>(p, iface, member, value); 153c1f4798dSBrad Bishop } 154d0f48adcSBrad Bishop } 155c1f4798dSBrad Bishop }; 156c1f4798dSBrad Bishop } 157c1f4798dSBrad Bishop 158f094d442SMatthew Barth /** @brief Get a property. 159f094d442SMatthew Barth * 160f094d442SMatthew Barth * Invoke the requested method with a reference to the requested 161f094d442SMatthew Barth * sdbusplus server binding interface as a parameter. 162f094d442SMatthew Barth * 163f094d442SMatthew Barth * @tparam T - The sdbusplus server binding interface type. 164f094d442SMatthew Barth * @tparam U - The type of the sdbusplus server binding member 165f094d442SMatthew Barth * function that sets the property. 166f094d442SMatthew Barth * 167f094d442SMatthew Barth * @param[in] path - The DBus path to get the property from. 168f094d442SMatthew Barth * @param[in] iface - The DBus interface hosting the property. 169f094d442SMatthew Barth * @param[in] member - Pointer to sdbusplus server binding member. 170f094d442SMatthew Barth * @param[in] prop - The property name to get the value from. 171f094d442SMatthew Barth * 172f094d442SMatthew Barth * @returns - A function object that gets the requested property. 173f094d442SMatthew Barth */ 174f094d442SMatthew Barth template <typename T, typename U> 175f094d442SMatthew Barth inline auto getProperty(const char* path, const char* iface, U&& member, 176f094d442SMatthew Barth const char* prop) 177f094d442SMatthew Barth { 178f094d442SMatthew Barth return [path, iface, member, prop](auto& mgr) { 179f094d442SMatthew Barth return mgr.template invokeMethod<T>(path, iface, member, prop); 180f094d442SMatthew Barth }; 181f094d442SMatthew Barth } 182f094d442SMatthew Barth 183c1f4798dSBrad Bishop /** @struct PropertyChangedCondition 184c1f4798dSBrad Bishop * @brief Match filter functor that tests a property value. 185c1f4798dSBrad Bishop * 186c1f4798dSBrad Bishop * @tparam T - The type of the property being tested. 187c1f4798dSBrad Bishop * @tparam U - The type of the condition checking functor. 188c1f4798dSBrad Bishop */ 189a680d1efSPatrick Venture template <typename T, typename U> 190a680d1efSPatrick Venture struct PropertyChangedCondition 191c1f4798dSBrad Bishop { 192c1f4798dSBrad Bishop PropertyChangedCondition() = delete; 193c1f4798dSBrad Bishop ~PropertyChangedCondition() = default; 194c1f4798dSBrad Bishop PropertyChangedCondition(const PropertyChangedCondition&) = default; 195615b2a8fSBrad Bishop PropertyChangedCondition& 196615b2a8fSBrad Bishop operator=(const PropertyChangedCondition&) = default; 197c1f4798dSBrad Bishop PropertyChangedCondition(PropertyChangedCondition&&) = default; 198c1f4798dSBrad Bishop PropertyChangedCondition& operator=(PropertyChangedCondition&&) = default; 199c1f4798dSBrad Bishop PropertyChangedCondition(const char* iface, const char* property, 200c1f4798dSBrad Bishop U&& condition) : 201c1f4798dSBrad Bishop _iface(iface), 202615b2a8fSBrad Bishop _property(property), _condition(std::forward<U>(condition)) 203615b2a8fSBrad Bishop { 204615b2a8fSBrad Bishop } 205c1f4798dSBrad Bishop 206c1f4798dSBrad Bishop /** @brief Test a property value. 207c1f4798dSBrad Bishop * 208c1f4798dSBrad Bishop * Extract the property from the PropertiesChanged 209c1f4798dSBrad Bishop * message and run the condition test. 210c1f4798dSBrad Bishop */ 211615b2a8fSBrad Bishop bool operator()(sdbusplus::bus::bus&, sdbusplus::message::message& msg, 212c1f4798dSBrad Bishop Manager&) const 213c1f4798dSBrad Bishop { 214*55f9eae4SPatrick Williams std::map<std::string, std::variant<T>> properties; 215c1f4798dSBrad Bishop const char* iface = nullptr; 216c1f4798dSBrad Bishop 217c1f4798dSBrad Bishop msg.read(iface); 218c1f4798dSBrad Bishop if (!iface || strcmp(iface, _iface)) 219c1f4798dSBrad Bishop { 220c1f4798dSBrad Bishop return false; 221c1f4798dSBrad Bishop } 222c1f4798dSBrad Bishop 223c1f4798dSBrad Bishop msg.read(properties); 224c1f4798dSBrad Bishop auto it = properties.find(_property); 225c1f4798dSBrad Bishop if (it == properties.cend()) 226c1f4798dSBrad Bishop { 227c1f4798dSBrad Bishop return false; 228c1f4798dSBrad Bishop } 229c1f4798dSBrad Bishop 23026f8668dSPatrick Williams return _condition(std::forward<T>(std::get<T>(it->second))); 231c1f4798dSBrad Bishop } 232c1f4798dSBrad Bishop 233c1f4798dSBrad Bishop private: 234c1f4798dSBrad Bishop const char* _iface; 235c1f4798dSBrad Bishop const char* _property; 236c1f4798dSBrad Bishop U _condition; 237c1f4798dSBrad Bishop }; 238c1f4798dSBrad Bishop 239c1f4798dSBrad Bishop /** @struct PropertyConditionBase 240c1f4798dSBrad Bishop * @brief Match filter functor that tests a property value. 241c1f4798dSBrad Bishop * 242c1f4798dSBrad Bishop * Base class for PropertyCondition - factored out code that 243c1f4798dSBrad Bishop * doesn't need to be templated. 244c1f4798dSBrad Bishop */ 245c1f4798dSBrad Bishop struct PropertyConditionBase 246c1f4798dSBrad Bishop { 247c1f4798dSBrad Bishop PropertyConditionBase() = delete; 248c1f4798dSBrad Bishop virtual ~PropertyConditionBase() = default; 249c1f4798dSBrad Bishop PropertyConditionBase(const PropertyConditionBase&) = default; 250c1f4798dSBrad Bishop PropertyConditionBase& operator=(const PropertyConditionBase&) = default; 251c1f4798dSBrad Bishop PropertyConditionBase(PropertyConditionBase&&) = default; 252c1f4798dSBrad Bishop PropertyConditionBase& operator=(PropertyConditionBase&&) = default; 253c1f4798dSBrad Bishop 254c1f4798dSBrad Bishop /** @brief Constructor 255c1f4798dSBrad Bishop * 256c1f4798dSBrad Bishop * The service argument can be nullptr. If something 257c1f4798dSBrad Bishop * else is provided the function will call the the 258c1f4798dSBrad Bishop * service directly. If omitted, the function will 259c1f4798dSBrad Bishop * look up the service in the ObjectMapper. 260c1f4798dSBrad Bishop * 261c1f4798dSBrad Bishop * @param path - The path of the object containing 262c1f4798dSBrad Bishop * the property to be tested. 263c1f4798dSBrad Bishop * @param iface - The interface hosting the property 264c1f4798dSBrad Bishop * to be tested. 265c1f4798dSBrad Bishop * @param property - The property to be tested. 266c1f4798dSBrad Bishop * @param service - The DBus service hosting the object. 267c1f4798dSBrad Bishop */ 268615b2a8fSBrad Bishop PropertyConditionBase(const char* path, const char* iface, 269615b2a8fSBrad Bishop const char* property, const char* service) : 270d0f48adcSBrad Bishop _path(path ? path : std::string()), 271615b2a8fSBrad Bishop _iface(iface), _property(property), _service(service) 272615b2a8fSBrad Bishop { 273615b2a8fSBrad Bishop } 274c1f4798dSBrad Bishop 275c1f4798dSBrad Bishop /** @brief Forward comparison to type specific implementation. */ 276c1f4798dSBrad Bishop virtual bool eval(sdbusplus::message::message&) const = 0; 277c1f4798dSBrad Bishop 278f094d442SMatthew Barth /** @brief Forward comparison to type specific implementation. */ 279f094d442SMatthew Barth virtual bool eval(Manager&) const = 0; 280f094d442SMatthew Barth 281c1f4798dSBrad Bishop /** @brief Test a property value. 282c1f4798dSBrad Bishop * 283c1f4798dSBrad Bishop * Make a DBus call and test the value of any property. 284c1f4798dSBrad Bishop */ 285615b2a8fSBrad Bishop bool operator()(sdbusplus::bus::bus&, sdbusplus::message::message&, 286c1f4798dSBrad Bishop Manager&) const; 287c1f4798dSBrad Bishop 288d0f48adcSBrad Bishop /** @brief Test a property value. 289d0f48adcSBrad Bishop * 290d0f48adcSBrad Bishop * Make a DBus call and test the value of any property. 291d0f48adcSBrad Bishop */ 292615b2a8fSBrad Bishop bool operator()(const std::string&, sdbusplus::bus::bus&, Manager&) const; 293d0f48adcSBrad Bishop 294c1f4798dSBrad Bishop private: 295c1f4798dSBrad Bishop std::string _path; 296c1f4798dSBrad Bishop std::string _iface; 297c1f4798dSBrad Bishop std::string _property; 298c1f4798dSBrad Bishop const char* _service; 299c1f4798dSBrad Bishop }; 300c1f4798dSBrad Bishop 301c1f4798dSBrad Bishop /** @struct PropertyCondition 302c1f4798dSBrad Bishop * @brief Match filter functor that tests a property value. 303c1f4798dSBrad Bishop * 304c1f4798dSBrad Bishop * @tparam T - The type of the property being tested. 305c1f4798dSBrad Bishop * @tparam U - The type of the condition checking functor. 306f094d442SMatthew Barth * @tparam V - The getProperty functor return type. 307c1f4798dSBrad Bishop */ 308f094d442SMatthew Barth template <typename T, typename U, typename V> 309c1f4798dSBrad Bishop struct PropertyCondition final : public PropertyConditionBase 310c1f4798dSBrad Bishop { 311c1f4798dSBrad Bishop PropertyCondition() = delete; 312c1f4798dSBrad Bishop ~PropertyCondition() = default; 313c1f4798dSBrad Bishop PropertyCondition(const PropertyCondition&) = default; 314c1f4798dSBrad Bishop PropertyCondition& operator=(const PropertyCondition&) = default; 315c1f4798dSBrad Bishop PropertyCondition(PropertyCondition&&) = default; 316c1f4798dSBrad Bishop PropertyCondition& operator=(PropertyCondition&&) = default; 317c1f4798dSBrad Bishop 318c1f4798dSBrad Bishop /** @brief Constructor 319c1f4798dSBrad Bishop * 320f094d442SMatthew Barth * The service & getProperty arguments can be nullptrs. 321f094d442SMatthew Barth * If something else is provided the function will call the the 322c1f4798dSBrad Bishop * service directly. If omitted, the function will 323c1f4798dSBrad Bishop * look up the service in the ObjectMapper. 324f094d442SMatthew Barth * The getProperty function will be called to retrieve a property 325f094d442SMatthew Barth * value when given and the property is hosted by inventory manager. 326f094d442SMatthew Barth * When not given, the condition will default to return that the 327f094d442SMatthew Barth * condition failed and will not be executed. 328c1f4798dSBrad Bishop * 329c1f4798dSBrad Bishop * @param path - The path of the object containing 330c1f4798dSBrad Bishop * the property to be tested. 331c1f4798dSBrad Bishop * @param iface - The interface hosting the property 332c1f4798dSBrad Bishop * to be tested. 333c1f4798dSBrad Bishop * @param property - The property to be tested. 334c1f4798dSBrad Bishop * @param condition - The test to run on the property. 335c1f4798dSBrad Bishop * @param service - The DBus service hosting the object. 336f094d442SMatthew Barth * @param getProperty - The function to get a property value 337f094d442SMatthew Barth * for the condition. 338c1f4798dSBrad Bishop */ 339615b2a8fSBrad Bishop PropertyCondition(const char* path, const char* iface, const char* property, 340f094d442SMatthew Barth U&& condition, const char* service, 341f094d442SMatthew Barth GetProperty<V>&& getProperty = nullptr) : 342c1f4798dSBrad Bishop PropertyConditionBase(path, iface, property, service), 343f094d442SMatthew Barth _condition(std::forward<decltype(condition)>(condition)), 344f094d442SMatthew Barth _getProperty(getProperty) 345615b2a8fSBrad Bishop { 346615b2a8fSBrad Bishop } 347c1f4798dSBrad Bishop 348c1f4798dSBrad Bishop /** @brief Test a property value. 349c1f4798dSBrad Bishop * 350c1f4798dSBrad Bishop * Make a DBus call and test the value of any property. 351c1f4798dSBrad Bishop */ 352c1f4798dSBrad Bishop bool eval(sdbusplus::message::message& msg) const override 353c1f4798dSBrad Bishop { 354*55f9eae4SPatrick Williams std::variant<T> value; 355c1f4798dSBrad Bishop msg.read(value); 35626f8668dSPatrick Williams return _condition(std::forward<T>(std::get<T>(value))); 357c1f4798dSBrad Bishop } 358c1f4798dSBrad Bishop 359f094d442SMatthew Barth /** @brief Retrieve a property value from inventory and test it. 360f094d442SMatthew Barth * 361f094d442SMatthew Barth * Get a property from the inventory manager and test the value. 362f094d442SMatthew Barth * Default to fail the test where no function is given to get the 363f094d442SMatthew Barth * property from the inventory manager. 364f094d442SMatthew Barth */ 365f094d442SMatthew Barth bool eval(Manager& mgr) const override 366f094d442SMatthew Barth { 367f094d442SMatthew Barth if (_getProperty) 368f094d442SMatthew Barth { 369f094d442SMatthew Barth auto variant = _getProperty(mgr); 37026f8668dSPatrick Williams auto value = std::get<T>(variant); 371f094d442SMatthew Barth return _condition(std::forward<T>(value)); 372f094d442SMatthew Barth } 373f094d442SMatthew Barth return false; 374f094d442SMatthew Barth } 375f094d442SMatthew Barth 376c1f4798dSBrad Bishop private: 377c1f4798dSBrad Bishop U _condition; 378f094d442SMatthew Barth GetProperty<V> _getProperty; 379c1f4798dSBrad Bishop }; 380c1f4798dSBrad Bishop 381c1f4798dSBrad Bishop /** @brief Implicit type deduction for constructing PropertyChangedCondition. */ 382c1f4798dSBrad Bishop template <typename T> 383615b2a8fSBrad Bishop auto propertyChangedTo(const char* iface, const char* property, T&& val) 384c1f4798dSBrad Bishop { 385a680d1efSPatrick Venture auto condition = [val = std::forward<T>(val)](T&& arg) { 386c1f4798dSBrad Bishop return arg == val; 387c1f4798dSBrad Bishop }; 388c1f4798dSBrad Bishop using U = decltype(condition); 389615b2a8fSBrad Bishop return PropertyChangedCondition<T, U>(iface, property, 390615b2a8fSBrad Bishop std::move(condition)); 391c1f4798dSBrad Bishop } 392c1f4798dSBrad Bishop 393c1f4798dSBrad Bishop /** @brief Implicit type deduction for constructing PropertyCondition. */ 394f094d442SMatthew Barth template <typename T, typename V = InterfaceVariantType> 395615b2a8fSBrad Bishop auto propertyIs(const char* path, const char* iface, const char* property, 396f094d442SMatthew Barth T&& val, const char* service = nullptr, 397f094d442SMatthew Barth GetProperty<V>&& getProperty = nullptr) 398c1f4798dSBrad Bishop { 399a680d1efSPatrick Venture auto condition = [val = std::forward<T>(val)](T&& arg) { 400c1f4798dSBrad Bishop return arg == val; 401c1f4798dSBrad Bishop }; 402c1f4798dSBrad Bishop using U = decltype(condition); 403f094d442SMatthew Barth return PropertyCondition<T, U, V>(path, iface, property, 404f094d442SMatthew Barth std::move(condition), service, 405f094d442SMatthew Barth std::move(getProperty)); 406c1f4798dSBrad Bishop } 407c1f4798dSBrad Bishop } // namespace functor 408c1f4798dSBrad Bishop } // namespace manager 409c1f4798dSBrad Bishop } // namespace inventory 410c1f4798dSBrad Bishop } // namespace phosphor 411c1f4798dSBrad Bishop 412c1f4798dSBrad Bishop // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 413