blob: 797880bd43f0a9d2fe0eab84a6a96e7cf119652d [file] [log] [blame]
Brad Bishop49aefb32016-10-19 11:54:14 -04001#pragma once
2
3#include <map>
4#include <memory>
5#include <string>
6#include <vector>
7#include <sdbusplus/server.hpp>
Brad Bishop03f4cd92017-02-03 15:17:21 -05008#include <xyz/openbmc_project/Inventory/Manager/server.hpp>
Brad Bishop67b788d2016-11-29 13:09:01 -05009#include "events.hpp"
Brad Bishopc1f47982017-02-09 01:27:38 -050010#include "functor.hpp"
Brad Bishop1157af12017-01-22 01:03:02 -050011#include "types.hpp"
Brad Bishop49aefb32016-10-19 11:54:14 -040012
13namespace phosphor
14{
15namespace inventory
16{
17namespace manager
18{
Brad Bishop451f8d92016-11-21 14:15:19 -050019
20template <typename T>
Brad Bishopa5cc34c2017-02-03 20:57:36 -050021using ServerObject = T;
Brad Bishop451f8d92016-11-21 14:15:19 -050022
23using ManagerIface =
Brad Bishop9aa5e2f2017-01-15 19:45:40 -050024 sdbusplus::xyz::openbmc_project::Inventory::server::Manager;
Brad Bishop451f8d92016-11-21 14:15:19 -050025
Brad Bishop65ffffa2016-11-29 12:31:31 -050026/** @struct MakeInterface
27 * @brief Adapt an sdbusplus interface proxy.
28 *
29 * Template instances are builder functions that create
30 * adapted sdbusplus interface proxy interface objects.
31 *
32 * @tparam T - The type of the interface being adapted.
33 */
34template <typename T>
35struct MakeInterface
36{
Brad Bishop150147a2017-02-08 23:57:46 -050037 static any_ns::any make(
Brad Bishop90c30bc2017-01-22 16:40:47 -050038 sdbusplus::bus::bus& bus,
39 const char* path,
Brad Bishopa5cc34c2017-02-03 20:57:36 -050040 const Interface& props)
Brad Bishop65ffffa2016-11-29 12:31:31 -050041 {
Brad Bishop9bbfcb12017-02-04 10:51:06 -050042 using PropertiesVariant = typename T::PropertiesVariant;
43 using InterfaceVariant =
44 std::map<std::string, PropertiesVariant>;
45
46 InterfaceVariant v;
47
48 for (const auto& p : props)
49 {
50 v.emplace(
51 p.first,
52 convertVariant<PropertiesVariant>(p.second));
53 }
54
55 return any_ns::any(std::make_shared<T>(bus, path, v));
Brad Bishop65ffffa2016-11-29 12:31:31 -050056 }
57};
Brad Bishop49aefb32016-10-19 11:54:14 -040058
59/** @class Manager
60 * @brief OpenBMC inventory manager implementation.
61 *
62 * A concrete implementation for the xyz.openbmc_project.Inventory.Manager
63 * DBus API.
64 */
65class Manager final :
Brad Bishop12f8a3c2017-02-09 00:02:00 -050066 public ServerObject<ManagerIface>
Brad Bishop49aefb32016-10-19 11:54:14 -040067{
68 public:
Brad Bishop7b337772017-01-12 16:11:24 -050069 Manager() = delete;
70 Manager(const Manager&) = delete;
71 Manager& operator=(const Manager&) = delete;
72 Manager(Manager&&) = default;
73 Manager& operator=(Manager&&) = default;
74 ~Manager() = default;
Brad Bishop49aefb32016-10-19 11:54:14 -040075
Brad Bishop7b337772017-01-12 16:11:24 -050076 /** @brief Construct an inventory manager.
77 *
78 * @param[in] bus - An sdbusplus bus connection.
79 * @param[in] busname - The DBus busname to own.
80 * @param[in] root - The DBus path on which to implement
81 * an inventory manager.
82 * @param[in] iface - The DBus inventory interface to implement.
83 */
84 Manager(sdbusplus::bus::bus&&, const char*, const char*, const char*);
Brad Bishop49aefb32016-10-19 11:54:14 -040085
Brad Bishop7b337772017-01-12 16:11:24 -050086 using EventInfo = std::tuple <
Brad Bishop12f8a3c2017-02-09 00:02:00 -050087 std::vector<EventBasePtr>,
88 std::vector<Action >>;
Brad Bishop49aefb32016-10-19 11:54:14 -040089
Brad Bishop7b337772017-01-12 16:11:24 -050090 /** @brief Start processing DBus messages. */
91 void run() noexcept;
Brad Bishop49aefb32016-10-19 11:54:14 -040092
Brad Bishop7b337772017-01-12 16:11:24 -050093 /** @brief Provided for testing only. */
94 void shutdown() noexcept;
Brad Bishop49aefb32016-10-19 11:54:14 -040095
Brad Bishop7b337772017-01-12 16:11:24 -050096 /** @brief sd_bus Notify method implementation callback. */
Brad Bishop03f4cd92017-02-03 15:17:21 -050097 void notify(
98 std::map<sdbusplus::message::object_path, Object> objs) override;
Brad Bishop49aefb32016-10-19 11:54:14 -040099
Brad Bishop48547a82017-01-19 15:12:50 -0500100 /** @brief Event processing entry point. */
101 void handleEvent(sdbusplus::message::message&,
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500102 const Event& event,
Brad Bishop48547a82017-01-19 15:12:50 -0500103 const EventInfo& info);
Brad Bishop49aefb32016-10-19 11:54:14 -0400104
Brad Bishop7b7e7122017-01-21 21:21:46 -0500105 /** @brief Drop one or more objects from DBus. */
106 void destroyObjects(
107 const std::vector<const char*>& paths);
Brad Bishop656a7d02016-10-19 22:20:02 -0400108
Brad Bishopeb68a682017-01-22 00:58:54 -0500109 /** @brief Add objects to DBus. */
110 void createObjects(
111 const std::map<sdbusplus::message::object_path, Object>& objs);
112
Brad Bishop7b337772017-01-12 16:11:24 -0500113 /** @brief Invoke an sdbusplus server binding method.
114 *
115 * Invoke the requested method with a reference to the requested
116 * sdbusplus server binding interface as a parameter.
117 *
118 * @tparam T - The sdbusplus server binding interface type.
119 * @tparam U - The type of the sdbusplus server binding member.
120 * @tparam Args - Argument types of the binding member.
121 *
122 * @param[in] path - The DBus path on which the method should
123 * be invoked.
124 * @param[in] interface - The DBus interface hosting the method.
125 * @param[in] member - Pointer to sdbusplus server binding member.
126 * @param[in] args - Arguments to forward to the binding member.
127 *
128 * @returns - The return/value type of the binding method being
129 * called.
130 */
131 template<typename T, typename U, typename ...Args>
132 decltype(auto) invokeMethod(const char* path, const char* interface,
133 U&& member, Args&& ...args)
134 {
Brad Bishop150147a2017-02-08 23:57:46 -0500135 auto& iface = getInterface<T>(path, interface);
Brad Bishop7b337772017-01-12 16:11:24 -0500136 return (iface.*member)(std::forward<Args>(args)...);
137 }
Brad Bishopda649b12016-11-30 14:35:02 -0500138
Brad Bishop7b337772017-01-12 16:11:24 -0500139 using SigArgs = std::vector <
140 std::unique_ptr <
141 std::tuple <
142 Manager*,
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500143 const DbusSignal*,
Brad Bishop7b337772017-01-12 16:11:24 -0500144 const EventInfo* >>>;
145 using SigArg = SigArgs::value_type::element_type;
Brad Bishop49aefb32016-10-19 11:54:14 -0400146
147 private:
Brad Bishop150147a2017-02-08 23:57:46 -0500148 using InterfaceComposite = std::map<std::string, any_ns::any>;
Brad Bishop7b337772017-01-12 16:11:24 -0500149 using ObjectReferences = std::map<std::string, InterfaceComposite>;
150 using Events = std::vector<EventInfo>;
Brad Bishop90c30bc2017-01-22 16:40:47 -0500151
152 // The int instantiation is safe since the signature of these
153 // functions don't change from one instantiation to the next.
154 using MakerType = std::add_pointer_t <
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500155 decltype(MakeInterface<int>::make) >;
Brad Bishop90c30bc2017-01-22 16:40:47 -0500156 using Makers = std::map<std::string, std::tuple<MakerType>>;
Brad Bishop49aefb32016-10-19 11:54:14 -0400157
Brad Bishop7b337772017-01-12 16:11:24 -0500158 /** @brief Provides weak references to interface holders.
159 *
160 * Common code for all types for the templated getInterface
161 * methods.
162 *
163 * @param[in] path - The DBus path for which the interface
164 * holder instance should be provided.
165 * @param[in] interface - The DBus interface for which the
166 * holder instance should be provided.
167 *
168 * @returns A weak reference to the holder instance.
169 */
Brad Bishop150147a2017-02-08 23:57:46 -0500170 const any_ns::any& getInterfaceHolder(
Brad Bishop7b337772017-01-12 16:11:24 -0500171 const char*, const char*) const;
Brad Bishop150147a2017-02-08 23:57:46 -0500172 any_ns::any& getInterfaceHolder(
Brad Bishop7b337772017-01-12 16:11:24 -0500173 const char*, const char*);
Brad Bishopb83a21e2016-11-30 13:43:37 -0500174
Brad Bishop7b337772017-01-12 16:11:24 -0500175 /** @brief Provides weak references to interface holders.
176 *
177 * @tparam T - The sdbusplus server binding interface type.
178 *
179 * @param[in] path - The DBus path for which the interface
180 * should be provided.
181 * @param[in] interface - The DBus interface to obtain.
182 *
183 * @returns A weak reference to the interface holder.
184 */
185 template<typename T>
186 auto& getInterface(const char* path, const char* interface)
187 {
188 auto& holder = getInterfaceHolder(path, interface);
Brad Bishop150147a2017-02-08 23:57:46 -0500189 return *any_ns::any_cast<std::shared_ptr<T> &>(holder);
Brad Bishop7b337772017-01-12 16:11:24 -0500190 }
191 template<typename T>
192 auto& getInterface(const char* path, const char* interface) const
193 {
194 auto& holder = getInterfaceHolder(path, interface);
Brad Bishop150147a2017-02-08 23:57:46 -0500195 return *any_ns::any_cast<T>(holder);
Brad Bishop7b337772017-01-12 16:11:24 -0500196 }
Brad Bishopb83a21e2016-11-30 13:43:37 -0500197
Brad Bishop7b337772017-01-12 16:11:24 -0500198 /** @brief Provided for testing only. */
Brad Bishopb9b929b2017-01-13 16:33:06 -0500199 volatile bool _shutdown;
Brad Bishop49aefb32016-10-19 11:54:14 -0400200
Brad Bishop7b337772017-01-12 16:11:24 -0500201 /** @brief Path prefix applied to any relative paths. */
202 const char* _root;
Brad Bishop49aefb32016-10-19 11:54:14 -0400203
Brad Bishop7b337772017-01-12 16:11:24 -0500204 /** @brief A container of sdbusplus server interface references. */
205 ObjectReferences _refs;
Brad Bishop49aefb32016-10-19 11:54:14 -0400206
Brad Bishop7b337772017-01-12 16:11:24 -0500207 /** @brief A container contexts for signal callbacks. */
208 SigArgs _sigargs;
Brad Bishop49aefb32016-10-19 11:54:14 -0400209
Brad Bishop7b337772017-01-12 16:11:24 -0500210 /** @brief A container of sdbusplus signal matches. */
211 std::vector<sdbusplus::server::match::match> _matches;
Brad Bishop49aefb32016-10-19 11:54:14 -0400212
Brad Bishop7b337772017-01-12 16:11:24 -0500213 /** @brief Persistent sdbusplus DBus bus connection. */
214 sdbusplus::bus::bus _bus;
Brad Bishop49aefb32016-10-19 11:54:14 -0400215
Brad Bishop7b337772017-01-12 16:11:24 -0500216 /** @brief sdbusplus org.freedesktop.DBus.ObjectManager reference. */
217 sdbusplus::server::manager::manager _manager;
Brad Bishop49aefb32016-10-19 11:54:14 -0400218
Brad Bishop7b337772017-01-12 16:11:24 -0500219 /** @brief A container of pimgen generated events and responses. */
220 static const Events _events;
Brad Bishop5fbaa7f2016-10-31 10:42:41 -0500221
Brad Bishop7b337772017-01-12 16:11:24 -0500222 /** @brief A container of pimgen generated factory methods. */
223 static const Makers _makers;
Brad Bishop49aefb32016-10-19 11:54:14 -0400224};
225
226} // namespace manager
227} // namespace inventory
228} // namespace phosphor
229
230// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4