blob: 11750b8751e7ae267d51d0c8ddda3a09923dd25e [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 Bishop79ccaf72017-01-22 16:00:50 -050026/** @struct PropertiesVariant
27 * @brief Wrapper for sdbusplus PropertiesVariant.
28 *
29 * A wrapper is useful since MakeInterface is instantiated with 'int'
30 * to deduce the return type of its methods, which does not depend
31 * on T.
32 *
33 * @tparam T - The sdbusplus server binding type.
34 */
35template <typename T, typename Enable = void>
36struct PropertiesVariant {};
37
38template <typename T>
39struct PropertiesVariant<T, typename std::enable_if<std::is_object<T>::value>::type>
40{
41 using Type = typename T::PropertiesVariant;
42};
43
44template <typename T>
45using PropertiesVariantType = typename PropertiesVariant<T>::Type;
46
Brad Bishop65ffffa2016-11-29 12:31:31 -050047/** @struct MakeInterface
48 * @brief Adapt an sdbusplus interface proxy.
49 *
50 * Template instances are builder functions that create
51 * adapted sdbusplus interface proxy interface objects.
52 *
53 * @tparam T - The type of the interface being adapted.
54 */
Brad Bishop79ccaf72017-01-22 16:00:50 -050055
Brad Bishop65ffffa2016-11-29 12:31:31 -050056template <typename T>
57struct MakeInterface
58{
Brad Bishop150147a2017-02-08 23:57:46 -050059 static any_ns::any make(
Brad Bishop90c30bc2017-01-22 16:40:47 -050060 sdbusplus::bus::bus& bus,
61 const char* path,
Brad Bishopa5cc34c2017-02-03 20:57:36 -050062 const Interface& props)
Brad Bishop65ffffa2016-11-29 12:31:31 -050063 {
Brad Bishop9bbfcb12017-02-04 10:51:06 -050064 using InterfaceVariant =
Brad Bishop79ccaf72017-01-22 16:00:50 -050065 std::map<std::string, PropertiesVariantType<T>>;
Brad Bishop9bbfcb12017-02-04 10:51:06 -050066
67 InterfaceVariant v;
68
69 for (const auto& p : props)
70 {
71 v.emplace(
72 p.first,
Brad Bishop79ccaf72017-01-22 16:00:50 -050073 convertVariant<PropertiesVariantType<T>>(p.second));
Brad Bishop9bbfcb12017-02-04 10:51:06 -050074 }
75
76 return any_ns::any(std::make_shared<T>(bus, path, v));
Brad Bishop65ffffa2016-11-29 12:31:31 -050077 }
Brad Bishop79ccaf72017-01-22 16:00:50 -050078
79 static void assign(const Interface& props, any_ns::any& holder)
80 {
81 auto& iface = *any_ns::any_cast<std::shared_ptr<T> &>(holder);
82 for (const auto& p : props)
83 {
84 iface.setPropertyByName(
85 p.first, convertVariant<PropertiesVariantType<T>>(p.second));
86 }
87 }
Brad Bishop65ffffa2016-11-29 12:31:31 -050088};
Brad Bishop49aefb32016-10-19 11:54:14 -040089
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 */
96class Manager final :
Brad Bishop12f8a3c2017-02-09 00:02:00 -050097 public ServerObject<ManagerIface>
Brad Bishop49aefb32016-10-19 11:54:14 -040098{
99 public:
Brad Bishop7b337772017-01-12 16:11:24 -0500100 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;
Brad Bishop49aefb32016-10-19 11:54:14 -0400106
Brad Bishop7b337772017-01-12 16:11:24 -0500107 /** @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*);
Brad Bishop49aefb32016-10-19 11:54:14 -0400116
Brad Bishop7b337772017-01-12 16:11:24 -0500117 using EventInfo = std::tuple <
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500118 std::vector<EventBasePtr>,
119 std::vector<Action >>;
Brad Bishop49aefb32016-10-19 11:54:14 -0400120
Brad Bishop7b337772017-01-12 16:11:24 -0500121 /** @brief Start processing DBus messages. */
122 void run() noexcept;
Brad Bishop49aefb32016-10-19 11:54:14 -0400123
Brad Bishop7b337772017-01-12 16:11:24 -0500124 /** @brief Provided for testing only. */
125 void shutdown() noexcept;
Brad Bishop49aefb32016-10-19 11:54:14 -0400126
Brad Bishop7b337772017-01-12 16:11:24 -0500127 /** @brief sd_bus Notify method implementation callback. */
Brad Bishop03f4cd92017-02-03 15:17:21 -0500128 void notify(
129 std::map<sdbusplus::message::object_path, Object> objs) override;
Brad Bishop49aefb32016-10-19 11:54:14 -0400130
Brad Bishop48547a82017-01-19 15:12:50 -0500131 /** @brief Event processing entry point. */
132 void handleEvent(sdbusplus::message::message&,
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500133 const Event& event,
Brad Bishop48547a82017-01-19 15:12:50 -0500134 const EventInfo& info);
Brad Bishop49aefb32016-10-19 11:54:14 -0400135
Brad Bishop7b7e7122017-01-21 21:21:46 -0500136 /** @brief Drop one or more objects from DBus. */
137 void destroyObjects(
138 const std::vector<const char*>& paths);
Brad Bishop656a7d02016-10-19 22:20:02 -0400139
Brad Bishopeb68a682017-01-22 00:58:54 -0500140 /** @brief Add objects to DBus. */
141 void createObjects(
142 const std::map<sdbusplus::message::object_path, Object>& objs);
143
Brad Bishop79ccaf72017-01-22 16:00:50 -0500144 /** @brief Add or update objects on DBus. */
145 void updateObjects(
146 const std::map<sdbusplus::message::object_path, Object>& objs);
147
Brad Bishop7b337772017-01-12 16:11:24 -0500148 /** @brief Invoke an sdbusplus server binding method.
149 *
150 * Invoke the requested method with a reference to the requested
151 * sdbusplus server binding interface as a parameter.
152 *
153 * @tparam T - The sdbusplus server binding interface type.
154 * @tparam U - The type of the sdbusplus server binding member.
155 * @tparam Args - Argument types of the binding member.
156 *
157 * @param[in] path - The DBus path on which the method should
158 * be invoked.
159 * @param[in] interface - The DBus interface hosting the method.
160 * @param[in] member - Pointer to sdbusplus server binding member.
161 * @param[in] args - Arguments to forward to the binding member.
162 *
163 * @returns - The return/value type of the binding method being
164 * called.
165 */
166 template<typename T, typename U, typename ...Args>
167 decltype(auto) invokeMethod(const char* path, const char* interface,
168 U&& member, Args&& ...args)
169 {
Brad Bishop150147a2017-02-08 23:57:46 -0500170 auto& iface = getInterface<T>(path, interface);
Brad Bishop7b337772017-01-12 16:11:24 -0500171 return (iface.*member)(std::forward<Args>(args)...);
172 }
Brad Bishopda649b12016-11-30 14:35:02 -0500173
Brad Bishop7b337772017-01-12 16:11:24 -0500174 using SigArgs = std::vector <
175 std::unique_ptr <
176 std::tuple <
177 Manager*,
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500178 const DbusSignal*,
Brad Bishop7b337772017-01-12 16:11:24 -0500179 const EventInfo* >>>;
180 using SigArg = SigArgs::value_type::element_type;
Brad Bishop49aefb32016-10-19 11:54:14 -0400181
182 private:
Brad Bishop150147a2017-02-08 23:57:46 -0500183 using InterfaceComposite = std::map<std::string, any_ns::any>;
Brad Bishop7b337772017-01-12 16:11:24 -0500184 using ObjectReferences = std::map<std::string, InterfaceComposite>;
185 using Events = std::vector<EventInfo>;
Brad Bishop90c30bc2017-01-22 16:40:47 -0500186
Brad Bishop79ccaf72017-01-22 16:00:50 -0500187 // The int instantiations are safe since the signature of these
Brad Bishop90c30bc2017-01-22 16:40:47 -0500188 // functions don't change from one instantiation to the next.
189 using MakerType = std::add_pointer_t <
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500190 decltype(MakeInterface<int>::make) >;
Brad Bishop79ccaf72017-01-22 16:00:50 -0500191 using AssignerType = std::add_pointer_t <
192 decltype(MakeInterface<int>::assign) >;
193 using Makers = std::map<std::string, std::tuple<MakerType, AssignerType>>;
Brad Bishop49aefb32016-10-19 11:54:14 -0400194
Brad Bishop7b337772017-01-12 16:11:24 -0500195 /** @brief Provides weak references to interface holders.
196 *
197 * Common code for all types for the templated getInterface
198 * methods.
199 *
200 * @param[in] path - The DBus path for which the interface
201 * holder instance should be provided.
202 * @param[in] interface - The DBus interface for which the
203 * holder instance should be provided.
204 *
205 * @returns A weak reference to the holder instance.
206 */
Brad Bishop150147a2017-02-08 23:57:46 -0500207 const any_ns::any& getInterfaceHolder(
Brad Bishop7b337772017-01-12 16:11:24 -0500208 const char*, const char*) const;
Brad Bishop150147a2017-02-08 23:57:46 -0500209 any_ns::any& getInterfaceHolder(
Brad Bishop7b337772017-01-12 16:11:24 -0500210 const char*, const char*);
Brad Bishopb83a21e2016-11-30 13:43:37 -0500211
Brad Bishop7b337772017-01-12 16:11:24 -0500212 /** @brief Provides weak references to interface holders.
213 *
214 * @tparam T - The sdbusplus server binding interface type.
215 *
216 * @param[in] path - The DBus path for which the interface
217 * should be provided.
218 * @param[in] interface - The DBus interface to obtain.
219 *
220 * @returns A weak reference to the interface holder.
221 */
222 template<typename T>
223 auto& getInterface(const char* path, const char* interface)
224 {
225 auto& holder = getInterfaceHolder(path, interface);
Brad Bishop150147a2017-02-08 23:57:46 -0500226 return *any_ns::any_cast<std::shared_ptr<T> &>(holder);
Brad Bishop7b337772017-01-12 16:11:24 -0500227 }
228 template<typename T>
229 auto& getInterface(const char* path, const char* interface) const
230 {
231 auto& holder = getInterfaceHolder(path, interface);
Brad Bishop150147a2017-02-08 23:57:46 -0500232 return *any_ns::any_cast<T>(holder);
Brad Bishop7b337772017-01-12 16:11:24 -0500233 }
Brad Bishopb83a21e2016-11-30 13:43:37 -0500234
Brad Bishop79ccaf72017-01-22 16:00:50 -0500235 /** @brief Add or update interfaces on DBus. */
236 void updateInterfaces(
237 const sdbusplus::message::object_path& path,
238 const Object& interfaces,
239 ObjectReferences::iterator pos,
240 bool emitSignals = true);
241
Brad Bishop7b337772017-01-12 16:11:24 -0500242 /** @brief Provided for testing only. */
Brad Bishopb9b929b2017-01-13 16:33:06 -0500243 volatile bool _shutdown;
Brad Bishop49aefb32016-10-19 11:54:14 -0400244
Brad Bishop7b337772017-01-12 16:11:24 -0500245 /** @brief Path prefix applied to any relative paths. */
246 const char* _root;
Brad Bishop49aefb32016-10-19 11:54:14 -0400247
Brad Bishop7b337772017-01-12 16:11:24 -0500248 /** @brief A container of sdbusplus server interface references. */
249 ObjectReferences _refs;
Brad Bishop49aefb32016-10-19 11:54:14 -0400250
Brad Bishop7b337772017-01-12 16:11:24 -0500251 /** @brief A container contexts for signal callbacks. */
252 SigArgs _sigargs;
Brad Bishop49aefb32016-10-19 11:54:14 -0400253
Brad Bishop7b337772017-01-12 16:11:24 -0500254 /** @brief A container of sdbusplus signal matches. */
255 std::vector<sdbusplus::server::match::match> _matches;
Brad Bishop49aefb32016-10-19 11:54:14 -0400256
Brad Bishop7b337772017-01-12 16:11:24 -0500257 /** @brief Persistent sdbusplus DBus bus connection. */
258 sdbusplus::bus::bus _bus;
Brad Bishop49aefb32016-10-19 11:54:14 -0400259
Brad Bishop7b337772017-01-12 16:11:24 -0500260 /** @brief sdbusplus org.freedesktop.DBus.ObjectManager reference. */
261 sdbusplus::server::manager::manager _manager;
Brad Bishop49aefb32016-10-19 11:54:14 -0400262
Brad Bishop7b337772017-01-12 16:11:24 -0500263 /** @brief A container of pimgen generated events and responses. */
264 static const Events _events;
Brad Bishop5fbaa7f2016-10-31 10:42:41 -0500265
Brad Bishop7b337772017-01-12 16:11:24 -0500266 /** @brief A container of pimgen generated factory methods. */
267 static const Makers _makers;
Brad Bishop49aefb32016-10-19 11:54:14 -0400268};
269
270} // namespace manager
271} // namespace inventory
272} // namespace phosphor
273
274// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4