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