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 Provided for testing only. */
120     bool _shutdown;
121 
122     /** @brief Path prefix applied to any relative paths. */
123     const char * _root;
124 
125     /** @brief A container of sdbusplus server interface references. */
126     ObjectReferences _refs;
127 
128     /** @brief A container contexts for signal callbacks. */
129     SigArgs _sigargs;
130 
131     /** @brief A container of sdbusplus signal matches.  */
132     std::vector<sdbusplus::server::match::match> _matches;
133 
134     /** @brief Persistent sdbusplus DBus bus connection. */
135     sdbusplus::bus::bus _bus;
136 
137     /** @brief sdbusplus org.freedesktop.DBus.ObjectManager reference. */
138     sdbusplus::server::manager::manager _manager;
139 
140     /** @brief A container of pimgen generated events and responses.  */
141     static const Events _events;
142 
143     /** @brief A container of pimgen generated factory methods.  */
144     static const Makers _makers;
145 };
146 
147 } // namespace manager
148 } // namespace inventory
149 } // namespace phosphor
150 
151 // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
152