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 */ 64 Manager(sdbusplus::bus::bus&&, 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, bool emitSignals, 182 bool restoreFromCache); 183 184 /** @brief Provided for testing only. */ 185 volatile bool _shutdown; 186 187 /** @brief Path prefix applied to any relative paths. */ 188 const char* _root; 189 190 /** @brief A container of sdbusplus server interface references. */ 191 ObjectReferences _refs; 192 193 /** @brief A container contexts for signal callbacks. */ 194 SigArgs _sigargs; 195 196 /** @brief A container of sdbusplus signal matches. */ 197 std::vector<sdbusplus::bus::match_t> _matches; 198 199 /** @brief Persistent sdbusplus DBus bus connection. */ 200 sdbusplus::bus::bus _bus; 201 202 /** @brief sdbusplus org.freedesktop.DBus.ObjectManager reference. */ 203 sdbusplus::server::manager::manager _manager; 204 205 /** @brief A container of pimgen generated events and responses. */ 206 static const Events _events; 207 208 /** @brief A container of pimgen generated factory methods. */ 209 static const Makers _makers; 210 211 /** @brief Handles creating mapper associations for inventory objects */ 212 #ifdef CREATE_ASSOCIATIONS 213 associations::Manager _associations; 214 #endif 215 }; 216 217 } // namespace manager 218 } // namespace inventory 219 } // namespace phosphor 220 221 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 222