1 #pragma once 2 3 #include <map> 4 #include <memory> 5 #include <string> 6 #include <vector> 7 #include <sdbusplus/server.hpp> 8 #include "xyz/openbmc_project/Inventory/Manager/server.hpp" 9 #include "events.hpp" 10 #include "actions.hpp" 11 12 namespace phosphor 13 { 14 namespace inventory 15 { 16 namespace manager 17 { 18 namespace details 19 { 20 21 template <typename T> 22 using ServerObject = typename sdbusplus::server::object::object<T>; 23 24 using ManagerIface = 25 sdbusplus::server::xyz::openbmc_project::Inventory::Manager; 26 27 /** @struct MakeInterface 28 * @brief Adapt an sdbusplus interface proxy. 29 * 30 * Template instances are builder functions that create 31 * adapted sdbusplus interface proxy interface objects. 32 * 33 * @tparam T - The type of the interface being adapted. 34 */ 35 template <typename T> 36 struct MakeInterface 37 { 38 static decltype(auto) make(sdbusplus::bus::bus &bus, const char *path) 39 { 40 using HolderType = holder::Holder<std::unique_ptr<T>>; 41 return static_cast<std::unique_ptr<holder::Base>>( 42 HolderType::template make_unique<HolderType>( 43 std::forward<std::unique_ptr<T>>( 44 std::make_unique<T>( 45 std::forward<decltype(bus)>(bus), 46 std::forward<decltype(path)>(path))))); 47 } 48 }; 49 } // namespace details 50 51 /** @class Manager 52 * @brief OpenBMC inventory manager implementation. 53 * 54 * A concrete implementation for the xyz.openbmc_project.Inventory.Manager 55 * DBus API. 56 */ 57 class Manager final : 58 public details::ServerObject<details::ManagerIface> 59 { 60 public: 61 Manager() = delete; 62 Manager(const Manager&) = delete; 63 Manager& operator=(const Manager&) = delete; 64 Manager(Manager&&) = default; 65 Manager& operator=(Manager&&) = default; 66 ~Manager() = default; 67 68 /** @brief Construct an inventory manager. 69 * 70 * @param[in] bus - An sdbusplus bus connection. 71 * @param[in] busname - The DBus busname to own. 72 * @param[in] root - The DBus path on which to implement 73 * an inventory manager. 74 * @param[in] iface - The DBus inventory interface to implement. 75 */ 76 Manager(sdbusplus::bus::bus &&, const char *, const char*, const char*); 77 78 using Object = std::map< 79 std::string, std::map< 80 std::string, sdbusplus::message::variant<std::string>>>; 81 using EventInfo = std::tuple< 82 std::vector<details::EventBasePtr>, 83 std::vector<details::ActionBasePtr>>; 84 85 /** @brief Start processing DBus messages. */ 86 void run() noexcept; 87 88 /** @brief Provided for testing only. */ 89 void shutdown() noexcept; 90 91 /** @brief sd_bus Notify method implementation callback. */ 92 void notify(std::string path, Object) override; 93 94 /** @brief sd_bus signal callback. */ 95 void signal(sdbusplus::message::message&, 96 const details::DbusSignal &event, 97 const EventInfo &info); 98 99 /** @brief Drop an object from DBus. */ 100 void destroyObject(const char *); 101 102 using SigArgs = std::vector< 103 std::unique_ptr< 104 std::tuple< 105 Manager *, 106 const details::DbusSignal *, 107 const EventInfo *>>>; 108 using SigArg = SigArgs::value_type::element_type; 109 110 private: 111 using HolderPtr = std::unique_ptr<details::holder::Base>; 112 using InterfaceComposite = std::map<std::string, HolderPtr>; 113 using ObjectReferences = std::map<std::string, InterfaceComposite>; 114 using Events = std::vector<EventInfo>; 115 using MakerType = HolderPtr(*)( 116 sdbusplus::bus::bus &, const char *); 117 using Makers = std::map<std::string, MakerType>; 118 119 /** @brief Provides weak references to interface holders. 120 * 121 * Common code for all types for the templated getInterface 122 * methods. 123 * 124 * @param[in] path - The DBus path for which the interface 125 * holder instance should be provided. 126 * @param[in] interface - The DBus interface for which the 127 * holder instance should be provided. 128 * 129 * @returns A weak reference to the holder instance. 130 */ 131 details::holder::Base& getInterfaceHolder( 132 const char *, const char *) const; 133 details::holder::Base& getInterfaceHolder( 134 const char *, const char *); 135 136 /** @brief Provides weak references to interface holders. 137 * 138 * @tparam T - The sdbusplus server binding interface type. 139 * 140 * @param[in] path - The DBus path for which the interface 141 * should be provided. 142 * @param[in] interface - The DBus interface to obtain. 143 * 144 * @returns A weak reference to the interface holder. 145 */ 146 template<typename T> 147 auto& getInterface(const char *path, const char *interface) 148 { 149 auto &holder = getInterfaceHolder(path, interface); 150 return static_cast< 151 details::holder::Holder<T> &>(holder); 152 } 153 template<typename T> 154 auto& getInterface(const char *path, const char *interface) const 155 { 156 auto &holder = getInterfaceHolder(path, interface); 157 return static_cast< 158 const details::holder::Holder<T> &>(holder); 159 } 160 161 /** @brief Provided for testing only. */ 162 bool _shutdown; 163 164 /** @brief Path prefix applied to any relative paths. */ 165 const char * _root; 166 167 /** @brief A container of sdbusplus server interface references. */ 168 ObjectReferences _refs; 169 170 /** @brief A container contexts for signal callbacks. */ 171 SigArgs _sigargs; 172 173 /** @brief A container of sdbusplus signal matches. */ 174 std::vector<sdbusplus::server::match::match> _matches; 175 176 /** @brief Persistent sdbusplus DBus bus connection. */ 177 sdbusplus::bus::bus _bus; 178 179 /** @brief sdbusplus org.freedesktop.DBus.ObjectManager reference. */ 180 sdbusplus::server::manager::manager _manager; 181 182 /** @brief A container of pimgen generated events and responses. */ 183 static const Events _events; 184 185 /** @brief A container of pimgen generated factory methods. */ 186 static const Makers _makers; 187 }; 188 189 } // namespace manager 190 } // namespace inventory 191 } // namespace phosphor 192 193 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 194