blob: e6c60a327e1c2ba84e8eaf7fd83402ab7ff0aa41 [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"
Deepak Kodihalli6620e982017-08-05 13:09:54 -050012#include "serialize.hpp"
Brad Bishop49aefb32016-10-19 11:54:14 -040013
14namespace phosphor
15{
16namespace inventory
17{
18namespace manager
19{
Brad Bishop451f8d92016-11-21 14:15:19 -050020
21template <typename T>
Brad Bishopa5cc34c2017-02-03 20:57:36 -050022using ServerObject = T;
Brad Bishop451f8d92016-11-21 14:15:19 -050023
24using ManagerIface =
Brad Bishop9aa5e2f2017-01-15 19:45:40 -050025 sdbusplus::xyz::openbmc_project::Inventory::server::Manager;
Brad Bishop451f8d92016-11-21 14:15:19 -050026
Brad Bishop79ccaf72017-01-22 16:00:50 -050027/** @struct PropertiesVariant
28 * @brief Wrapper for sdbusplus PropertiesVariant.
29 *
30 * A wrapper is useful since MakeInterface is instantiated with 'int'
31 * to deduce the return type of its methods, which does not depend
32 * on T.
33 *
34 * @tparam T - The sdbusplus server binding type.
35 */
36template <typename T, typename Enable = void>
37struct PropertiesVariant {};
38
39template <typename T>
40struct PropertiesVariant<T, typename std::enable_if<std::is_object<T>::value>::type>
41{
42 using Type = typename T::PropertiesVariant;
43};
44
45template <typename T>
46using PropertiesVariantType = typename PropertiesVariant<T>::Type;
47
Brad Bishop65ffffa2016-11-29 12:31:31 -050048/** @struct MakeInterface
49 * @brief Adapt an sdbusplus interface proxy.
50 *
51 * Template instances are builder functions that create
52 * adapted sdbusplus interface proxy interface objects.
53 *
54 * @tparam T - The type of the interface being adapted.
55 */
Brad Bishop79ccaf72017-01-22 16:00:50 -050056
Brad Bishop65ffffa2016-11-29 12:31:31 -050057template <typename T>
58struct MakeInterface
59{
Brad Bishop150147a2017-02-08 23:57:46 -050060 static any_ns::any make(
Brad Bishop90c30bc2017-01-22 16:40:47 -050061 sdbusplus::bus::bus& bus,
62 const char* path,
Brad Bishopa5cc34c2017-02-03 20:57:36 -050063 const Interface& props)
Brad Bishop65ffffa2016-11-29 12:31:31 -050064 {
Brad Bishop9bbfcb12017-02-04 10:51:06 -050065 using InterfaceVariant =
Brad Bishop79ccaf72017-01-22 16:00:50 -050066 std::map<std::string, PropertiesVariantType<T>>;
Brad Bishop9bbfcb12017-02-04 10:51:06 -050067
68 InterfaceVariant v;
69
70 for (const auto& p : props)
71 {
72 v.emplace(
73 p.first,
Brad Bishop79ccaf72017-01-22 16:00:50 -050074 convertVariant<PropertiesVariantType<T>>(p.second));
Brad Bishop9bbfcb12017-02-04 10:51:06 -050075 }
76
77 return any_ns::any(std::make_shared<T>(bus, path, v));
Brad Bishop65ffffa2016-11-29 12:31:31 -050078 }
Brad Bishop79ccaf72017-01-22 16:00:50 -050079
80 static void assign(const Interface& props, any_ns::any& holder)
81 {
82 auto& iface = *any_ns::any_cast<std::shared_ptr<T> &>(holder);
83 for (const auto& p : props)
84 {
85 iface.setPropertyByName(
86 p.first, convertVariant<PropertiesVariantType<T>>(p.second));
87 }
88 }
Deepak Kodihalli6620e982017-08-05 13:09:54 -050089
90 static void serialize(const std::string& path, const std::string& iface,
91 const any_ns::any& holder)
92 {
93 const auto& object =
94 *any_ns::any_cast<const std::shared_ptr<T> &>(holder);
95 cereal::serialize(path, iface, object);
96 }
Deepak Kodihallib28990f2017-08-08 07:19:34 -050097
98 static void deserialize(const std::string& path, const std::string& iface,
99 any_ns::any& holder)
100 {
101 auto& object = *any_ns::any_cast<std::shared_ptr<T> &>(holder);
102 cereal::deserialize(path, iface, object);
103 }
Brad Bishop65ffffa2016-11-29 12:31:31 -0500104};
Brad Bishop49aefb32016-10-19 11:54:14 -0400105
106/** @class Manager
107 * @brief OpenBMC inventory manager implementation.
108 *
109 * A concrete implementation for the xyz.openbmc_project.Inventory.Manager
110 * DBus API.
111 */
112class Manager final :
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500113 public ServerObject<ManagerIface>
Brad Bishop49aefb32016-10-19 11:54:14 -0400114{
115 public:
Brad Bishop7b337772017-01-12 16:11:24 -0500116 Manager() = delete;
117 Manager(const Manager&) = delete;
118 Manager& operator=(const Manager&) = delete;
119 Manager(Manager&&) = default;
120 Manager& operator=(Manager&&) = default;
121 ~Manager() = default;
Brad Bishop49aefb32016-10-19 11:54:14 -0400122
Brad Bishop7b337772017-01-12 16:11:24 -0500123 /** @brief Construct an inventory manager.
124 *
125 * @param[in] bus - An sdbusplus bus connection.
126 * @param[in] busname - The DBus busname to own.
127 * @param[in] root - The DBus path on which to implement
128 * an inventory manager.
129 * @param[in] iface - The DBus inventory interface to implement.
130 */
131 Manager(sdbusplus::bus::bus&&, const char*, const char*, const char*);
Brad Bishop49aefb32016-10-19 11:54:14 -0400132
Brad Bishop7b337772017-01-12 16:11:24 -0500133 using EventInfo = std::tuple <
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500134 std::vector<EventBasePtr>,
135 std::vector<Action >>;
Brad Bishop49aefb32016-10-19 11:54:14 -0400136
Brad Bishop7b337772017-01-12 16:11:24 -0500137 /** @brief Start processing DBus messages. */
138 void run() noexcept;
Brad Bishop49aefb32016-10-19 11:54:14 -0400139
Brad Bishop7b337772017-01-12 16:11:24 -0500140 /** @brief Provided for testing only. */
141 void shutdown() noexcept;
Brad Bishop49aefb32016-10-19 11:54:14 -0400142
Brad Bishop7b337772017-01-12 16:11:24 -0500143 /** @brief sd_bus Notify method implementation callback. */
Brad Bishop03f4cd92017-02-03 15:17:21 -0500144 void notify(
145 std::map<sdbusplus::message::object_path, Object> objs) override;
Brad Bishop49aefb32016-10-19 11:54:14 -0400146
Brad Bishop48547a82017-01-19 15:12:50 -0500147 /** @brief Event processing entry point. */
148 void handleEvent(sdbusplus::message::message&,
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500149 const Event& event,
Brad Bishop48547a82017-01-19 15:12:50 -0500150 const EventInfo& info);
Brad Bishop49aefb32016-10-19 11:54:14 -0400151
Brad Bishop7b7e7122017-01-21 21:21:46 -0500152 /** @brief Drop one or more objects from DBus. */
153 void destroyObjects(
154 const std::vector<const char*>& paths);
Brad Bishop656a7d02016-10-19 22:20:02 -0400155
Brad Bishopeb68a682017-01-22 00:58:54 -0500156 /** @brief Add objects to DBus. */
157 void createObjects(
158 const std::map<sdbusplus::message::object_path, Object>& objs);
159
Brad Bishop79ccaf72017-01-22 16:00:50 -0500160 /** @brief Add or update objects on DBus. */
161 void updateObjects(
Deepak Kodihallib28990f2017-08-08 07:19:34 -0500162 const std::map<sdbusplus::message::object_path, Object>& objs,
163 bool restoreFromCache = false);
164
165 /** @brief Restore persistent inventory items */
166 void restore();
Brad Bishop79ccaf72017-01-22 16:00:50 -0500167
Brad Bishop7b337772017-01-12 16:11:24 -0500168 /** @brief Invoke an sdbusplus server binding method.
169 *
170 * Invoke the requested method with a reference to the requested
171 * sdbusplus server binding interface as a parameter.
172 *
173 * @tparam T - The sdbusplus server binding interface type.
174 * @tparam U - The type of the sdbusplus server binding member.
175 * @tparam Args - Argument types of the binding member.
176 *
177 * @param[in] path - The DBus path on which the method should
178 * be invoked.
179 * @param[in] interface - The DBus interface hosting the method.
180 * @param[in] member - Pointer to sdbusplus server binding member.
181 * @param[in] args - Arguments to forward to the binding member.
182 *
183 * @returns - The return/value type of the binding method being
184 * called.
185 */
186 template<typename T, typename U, typename ...Args>
187 decltype(auto) invokeMethod(const char* path, const char* interface,
188 U&& member, Args&& ...args)
189 {
Brad Bishop150147a2017-02-08 23:57:46 -0500190 auto& iface = getInterface<T>(path, interface);
Brad Bishop7b337772017-01-12 16:11:24 -0500191 return (iface.*member)(std::forward<Args>(args)...);
192 }
Brad Bishopda649b12016-11-30 14:35:02 -0500193
Brad Bishop7b337772017-01-12 16:11:24 -0500194 using SigArgs = std::vector <
195 std::unique_ptr <
196 std::tuple <
197 Manager*,
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500198 const DbusSignal*,
Brad Bishop7b337772017-01-12 16:11:24 -0500199 const EventInfo* >>>;
200 using SigArg = SigArgs::value_type::element_type;
Brad Bishop49aefb32016-10-19 11:54:14 -0400201
202 private:
Brad Bishop150147a2017-02-08 23:57:46 -0500203 using InterfaceComposite = std::map<std::string, any_ns::any>;
Brad Bishop7b337772017-01-12 16:11:24 -0500204 using ObjectReferences = std::map<std::string, InterfaceComposite>;
205 using Events = std::vector<EventInfo>;
Brad Bishop90c30bc2017-01-22 16:40:47 -0500206
Brad Bishop79ccaf72017-01-22 16:00:50 -0500207 // The int instantiations are safe since the signature of these
Brad Bishop90c30bc2017-01-22 16:40:47 -0500208 // functions don't change from one instantiation to the next.
209 using MakerType = std::add_pointer_t <
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500210 decltype(MakeInterface<int>::make) >;
Brad Bishop79ccaf72017-01-22 16:00:50 -0500211 using AssignerType = std::add_pointer_t <
212 decltype(MakeInterface<int>::assign) >;
Deepak Kodihalli6620e982017-08-05 13:09:54 -0500213 using SerializerType = std::add_pointer_t <
214 decltype(MakeInterface<int>::serialize) >;
Deepak Kodihallib28990f2017-08-08 07:19:34 -0500215 using DeserializerType = std::add_pointer_t <
216 decltype(MakeInterface<int>::deserialize) >;
Deepak Kodihalli6620e982017-08-05 13:09:54 -0500217 using Makers = std::map<std::string,
Deepak Kodihallib28990f2017-08-08 07:19:34 -0500218 std::tuple<MakerType, AssignerType,
219 SerializerType, DeserializerType>>;
Brad Bishop49aefb32016-10-19 11:54:14 -0400220
Brad Bishop7b337772017-01-12 16:11:24 -0500221 /** @brief Provides weak references to interface holders.
222 *
223 * Common code for all types for the templated getInterface
224 * methods.
225 *
226 * @param[in] path - The DBus path for which the interface
227 * holder instance should be provided.
228 * @param[in] interface - The DBus interface for which the
229 * holder instance should be provided.
230 *
231 * @returns A weak reference to the holder instance.
232 */
Brad Bishop150147a2017-02-08 23:57:46 -0500233 const any_ns::any& getInterfaceHolder(
Brad Bishop7b337772017-01-12 16:11:24 -0500234 const char*, const char*) const;
Brad Bishop150147a2017-02-08 23:57:46 -0500235 any_ns::any& getInterfaceHolder(
Brad Bishop7b337772017-01-12 16:11:24 -0500236 const char*, const char*);
Brad Bishopb83a21e2016-11-30 13:43:37 -0500237
Brad Bishop7b337772017-01-12 16:11:24 -0500238 /** @brief Provides weak references to interface holders.
239 *
240 * @tparam T - The sdbusplus server binding interface type.
241 *
242 * @param[in] path - The DBus path for which the interface
243 * should be provided.
244 * @param[in] interface - The DBus interface to obtain.
245 *
246 * @returns A weak reference to the interface holder.
247 */
248 template<typename T>
249 auto& getInterface(const char* path, const char* interface)
250 {
251 auto& holder = getInterfaceHolder(path, interface);
Brad Bishop150147a2017-02-08 23:57:46 -0500252 return *any_ns::any_cast<std::shared_ptr<T> &>(holder);
Brad Bishop7b337772017-01-12 16:11:24 -0500253 }
254 template<typename T>
255 auto& getInterface(const char* path, const char* interface) const
256 {
257 auto& holder = getInterfaceHolder(path, interface);
Brad Bishop150147a2017-02-08 23:57:46 -0500258 return *any_ns::any_cast<T>(holder);
Brad Bishop7b337772017-01-12 16:11:24 -0500259 }
Brad Bishopb83a21e2016-11-30 13:43:37 -0500260
Brad Bishop79ccaf72017-01-22 16:00:50 -0500261 /** @brief Add or update interfaces on DBus. */
262 void updateInterfaces(
263 const sdbusplus::message::object_path& path,
264 const Object& interfaces,
265 ObjectReferences::iterator pos,
Deepak Kodihallib28990f2017-08-08 07:19:34 -0500266 bool emitSignals = true,
267 bool restoreFromCache = false);
Brad Bishop79ccaf72017-01-22 16:00:50 -0500268
Brad Bishop7b337772017-01-12 16:11:24 -0500269 /** @brief Provided for testing only. */
Brad Bishopb9b929b2017-01-13 16:33:06 -0500270 volatile bool _shutdown;
Brad Bishop49aefb32016-10-19 11:54:14 -0400271
Brad Bishop7b337772017-01-12 16:11:24 -0500272 /** @brief Path prefix applied to any relative paths. */
273 const char* _root;
Brad Bishop49aefb32016-10-19 11:54:14 -0400274
Brad Bishop7b337772017-01-12 16:11:24 -0500275 /** @brief A container of sdbusplus server interface references. */
276 ObjectReferences _refs;
Brad Bishop49aefb32016-10-19 11:54:14 -0400277
Brad Bishop7b337772017-01-12 16:11:24 -0500278 /** @brief A container contexts for signal callbacks. */
279 SigArgs _sigargs;
Brad Bishop49aefb32016-10-19 11:54:14 -0400280
Brad Bishop7b337772017-01-12 16:11:24 -0500281 /** @brief A container of sdbusplus signal matches. */
Patrick Williams133ca132017-05-01 22:12:34 -0500282 std::vector<sdbusplus::bus::match_t> _matches;
Brad Bishop49aefb32016-10-19 11:54:14 -0400283
Brad Bishop7b337772017-01-12 16:11:24 -0500284 /** @brief Persistent sdbusplus DBus bus connection. */
285 sdbusplus::bus::bus _bus;
Brad Bishop49aefb32016-10-19 11:54:14 -0400286
Brad Bishop7b337772017-01-12 16:11:24 -0500287 /** @brief sdbusplus org.freedesktop.DBus.ObjectManager reference. */
288 sdbusplus::server::manager::manager _manager;
Brad Bishop49aefb32016-10-19 11:54:14 -0400289
Brad Bishop7b337772017-01-12 16:11:24 -0500290 /** @brief A container of pimgen generated events and responses. */
291 static const Events _events;
Brad Bishop5fbaa7f2016-10-31 10:42:41 -0500292
Brad Bishop7b337772017-01-12 16:11:24 -0500293 /** @brief A container of pimgen generated factory methods. */
294 static const Makers _makers;
Brad Bishop49aefb32016-10-19 11:54:14 -0400295};
296
297} // namespace manager
298} // namespace inventory
299} // namespace phosphor
300
301// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4