blob: 36d47a672983dfb6b3fb854fa98a310bcb856a0a [file] [log] [blame]
Brad Bishop49aefb32016-10-19 11:54:14 -04001/**
2 * Copyright © 2016 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <iostream>
17#include <exception>
18#include "manager.hpp"
19
20namespace phosphor
21{
22namespace inventory
23{
24namespace manager
25{
26namespace details
27{
28
29/** @brief Fowrarding signal callback.
30 *
31 * Extracts per-signal specific context and forwards the call to the manager
32 * instance.
33 */
34auto _signal(sd_bus_message *m, void *data, sd_bus_error *e) noexcept
35{
36 try {
37 auto msg = sdbusplus::message::message(m);
38 auto &args = *static_cast<Manager::SigArg*>(data);
39 sd_bus_message_ref(m);
40 auto &mgr = *std::get<0>(args);
41 mgr.signal(msg, *std::get<1>(args));
42 }
43 catch (const std::exception &e) {
44 std::cerr << e.what() << std::endl;
45 }
46
47 return 0;
48}
49
50} // namespace details
51
52Manager::Manager(
53 sdbusplus::bus::bus &&bus,
54 const char *busname,
55 const char *root,
56 const char *iface) :
57 sdbusplus::server::xyz::openbmc_project::Inventory::Manager(bus, root),
58 _shutdown(false),
59 _root(root),
60 _bus(std::move(bus)),
61 _manager(sdbusplus::server::manager::manager(_bus, root))
62{
63 for (auto &x: _events) {
64 // Create a callback context for each event.
65 _sigargs.emplace_back(
66 std::make_unique<SigArg>(
67 std::make_tuple(
68 this,
69 &x.second)));
70 // Register our callback and the context for
71 // each event.
72 _matches.emplace_back(
73 sdbusplus::server::match::match(
74 _bus,
75 std::get<0>(x.second),
76 details::_signal,
77 _sigargs.back().get()));
78 }
79
80 _bus.request_name(busname);
81}
82
83void Manager::shutdown() noexcept
84{
85 _shutdown = true;
86}
87
88void Manager::run() noexcept
89{
90 while(!_shutdown) {
91 try {
92 _bus.process_discard();
93 _bus.wait(5000000);
94 }
95 catch (const std::exception &e) {
96 std::cerr << e.what() << std::endl;
97 }
98 }
99}
100
101void Manager::notify(std::string path, Object object)
102{
103 try {
104 using MakerType = HolderPtr(*)(
105 sdbusplus::bus::bus &, const char *);
106 using Makers = std::map<std::string, MakerType>;
107
108 if(object.cbegin() == object.cend())
109 throw std::runtime_error(
110 "No interfaces in " + path);
111
112 static const Makers makers{
113 // TODO - Add mappings here.
114 };
115
116 path.insert(0, _root);
117
118 auto obj = _refs.find(path);
119 if(obj != _refs.end())
120 throw std::runtime_error(
121 obj->first + " already exists");
122
123 // Create an interface holder for each interface
124 // provided by the client and group them into
125 // a container.
126 InterfaceComposite ref;
127
128 for (auto &x: object) {
129 auto maker = makers.find(x.first.c_str());
130
131 if(maker == makers.end())
132 throw std::runtime_error(
133 "Unimplemented interface: " + x.first);
134
135 ref.emplace(
136 std::make_pair(
137 x.first,
138 (maker->second)(_bus, path.c_str())));
139 }
140
141 // Hang on to a reference to the object (interfaces)
142 // so it stays on the bus, and so we can make calls
143 // to it if needed.
144 _refs.emplace(
145 std::make_pair(
146 path, std::move(ref)));
147 }
148 catch (const std::exception &e) {
149 std::cerr << e.what() << std::endl;
150 }
151}
152
153void Manager::signal(sdbusplus::message::message &msg, auto &args)
154{
155 // TODO - unstub
156}
157
158#include "generated.hpp"
159
160} // namespace manager
161} // namespace inventory
162} // namespace phosphor
163
164// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4