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