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