1 #pragma once 2 3 #include "events.hpp" 4 #include "functor.hpp" 5 #include "interface_ops.hpp" 6 #include "serialize.hpp" 7 #include "types.hpp" 8 #ifdef CREATE_ASSOCIATIONS 9 #include "association_manager.hpp" 10 #endif 11 12 #include <sdbusplus/server.hpp> 13 #include <xyz/openbmc_project/Inventory/Manager/server.hpp> 14 15 #include <any> 16 #include <map> 17 #include <memory> 18 #include <string> 19 #include <vector> 20 21 namespace sdbusplus 22 { 23 namespace bus 24 { 25 class bus; 26 } 27 } // namespace sdbusplus 28 namespace phosphor 29 { 30 namespace inventory 31 { 32 namespace manager 33 { 34 35 template <typename T> 36 using ServerObject = T; 37 38 using ManagerIface = 39 sdbusplus::xyz::openbmc_project::Inventory::server::Manager; 40 41 /** @class Manager 42 * @brief OpenBMC inventory manager implementation. 43 * 44 * A concrete implementation for the xyz.openbmc_project.Inventory.Manager 45 * DBus API. 46 */ 47 class Manager final : public ServerObject<ManagerIface> 48 { 49 public: 50 Manager() = delete; 51 Manager(const Manager&) = delete; 52 Manager& operator=(const Manager&) = delete; 53 Manager(Manager&&) = default; 54 Manager& operator=(Manager&&) = default; 55 ~Manager() = default; 56 57 /** @brief Construct an inventory manager. 58 * 59 * @param[in] bus - An sdbusplus bus connection. 60 * @param[in] busname - The DBus busname to own. 61 * @param[in] root - The DBus path on which to implement 62 * an inventory manager. 63 * @param[in] iface - The DBus inventory interface to implement. 64 */ 65 Manager(sdbusplus::bus::bus&&, const char*, const char*, const char*); 66 67 using EventInfo = 68 std::tuple<std::vector<EventBasePtr>, std::vector<Action>>; 69 70 /** @brief Start processing DBus messages. */ 71 void run() noexcept; 72 73 /** @brief Provided for testing only. */ 74 void shutdown() noexcept; 75 76 /** @brief sd_bus Notify method implementation callback. */ 77 void 78 notify(std::map<sdbusplus::message::object_path, Object> objs) override; 79 80 /** @brief Event processing entry point. */ 81 void handleEvent(sdbusplus::message::message&, const Event& event, 82 const EventInfo& info); 83 84 /** @brief Drop one or more objects from DBus. */ 85 void destroyObjects(const std::vector<const char*>& paths); 86 87 /** @brief Add objects to DBus. */ 88 void createObjects( 89 const std::map<sdbusplus::message::object_path, Object>& objs); 90 91 /** @brief Add or update objects on DBus. */ 92 void updateObjects( 93 const std::map<sdbusplus::message::object_path, Object>& objs, 94 bool restoreFromCache = false); 95 96 /** @brief Restore persistent inventory items */ 97 void restore(); 98 99 /** @brief Invoke an sdbusplus server binding method. 100 * 101 * Invoke the requested method with a reference to the requested 102 * sdbusplus server binding interface as a parameter. 103 * 104 * @tparam T - The sdbusplus server binding interface type. 105 * @tparam U - The type of the sdbusplus server binding member. 106 * @tparam Args - Argument types of the binding member. 107 * 108 * @param[in] path - The DBus path on which the method should 109 * be invoked. 110 * @param[in] interface - The DBus interface hosting the method. 111 * @param[in] member - Pointer to sdbusplus server binding member. 112 * @param[in] args - Arguments to forward to the binding member. 113 * 114 * @returns - The return/value type of the binding method being 115 * called. 116 */ 117 template <typename T, typename U, typename... Args> 118 decltype(auto) invokeMethod(const char* path, const char* interface, 119 U&& member, Args&&... args) 120 { 121 auto& iface = getInterface<T>(path, interface); 122 return (iface.*member)(std::forward<Args>(args)...); 123 } 124 125 using SigArgs = std::vector<std::unique_ptr< 126 std::tuple<Manager*, const DbusSignal*, const EventInfo*>>>; 127 using SigArg = SigArgs::value_type::element_type; 128 129 private: 130 using InterfaceComposite = std::map<std::string, std::any>; 131 using ObjectReferences = std::map<std::string, InterfaceComposite>; 132 using Events = std::vector<EventInfo>; 133 134 // The int instantiations are safe since the signature of these 135 // functions don't change from one instantiation to the next. 136 using Makers = 137 std::map<std::string, std::tuple<MakeInterfaceType, AssignInterfaceType, 138 SerializeInterfaceType<SerialOps>, 139 DeserializeInterfaceType<SerialOps>>>; 140 141 /** @brief Provides weak references to interface holders. 142 * 143 * Common code for all types for the templated getInterface 144 * methods. 145 * 146 * @param[in] path - The DBus path for which the interface 147 * holder instance should be provided. 148 * @param[in] interface - The DBus interface for which the 149 * holder instance should be provided. 150 * 151 * @returns A weak reference to the holder instance. 152 */ 153 const std::any& getInterfaceHolder(const char*, const char*) const; 154 std::any& getInterfaceHolder(const char*, const char*); 155 156 /** @brief Provides weak references to interface holders. 157 * 158 * @tparam T - The sdbusplus server binding interface type. 159 * 160 * @param[in] path - The DBus path for which the interface 161 * should be provided. 162 * @param[in] interface - The DBus interface to obtain. 163 * 164 * @returns A weak reference to the interface holder. 165 */ 166 template <typename T> 167 auto& getInterface(const char* path, const char* interface) 168 { 169 auto& holder = getInterfaceHolder(path, interface); 170 return *std::any_cast<std::shared_ptr<T>&>(holder); 171 } 172 template <typename T> 173 auto& getInterface(const char* path, const char* interface) const 174 { 175 auto& holder = getInterfaceHolder(path, interface); 176 return *std::any_cast<T>(holder); 177 } 178 179 /** @brief Add or update interfaces on DBus. */ 180 void updateInterfaces(const sdbusplus::message::object_path& path, 181 const Object& interfaces, 182 ObjectReferences::iterator pos, 183 bool emitSignals = true, 184 bool restoreFromCache = false); 185 186 /** @brief Provided for testing only. */ 187 volatile bool _shutdown; 188 189 /** @brief Path prefix applied to any relative paths. */ 190 const char* _root; 191 192 /** @brief A container of sdbusplus server interface references. */ 193 ObjectReferences _refs; 194 195 /** @brief A container contexts for signal callbacks. */ 196 SigArgs _sigargs; 197 198 /** @brief A container of sdbusplus signal matches. */ 199 std::vector<sdbusplus::bus::match_t> _matches; 200 201 /** @brief Persistent sdbusplus DBus bus connection. */ 202 sdbusplus::bus::bus _bus; 203 204 /** @brief sdbusplus org.freedesktop.DBus.ObjectManager reference. */ 205 sdbusplus::server::manager::manager _manager; 206 207 /** @brief A container of pimgen generated events and responses. */ 208 static const Events _events; 209 210 /** @brief A container of pimgen generated factory methods. */ 211 static const Makers _makers; 212 213 /** @brief Handles creating mapper associations for inventory objects */ 214 #ifdef CREATE_ASSOCIATIONS 215 associations::Manager _associations; 216 #endif 217 }; 218 219 } // namespace manager 220 } // namespace inventory 221 } // namespace phosphor 222 223 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 224