blob: c62c288a3a82774a16d845bc12aaf2a9ba65bd27 [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) :
Brad Bishop451f8d92016-11-21 14:15:19 -050057 details::ServerObject<details::ManagerIface>(bus, root),
Brad Bishop49aefb32016-10-19 11:54:14 -040058 _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 {
Brad Bishop49aefb32016-10-19 11:54:14 -0400104 if(object.cbegin() == object.cend())
105 throw std::runtime_error(
106 "No interfaces in " + path);
107
Brad Bishop49aefb32016-10-19 11:54:14 -0400108 path.insert(0, _root);
109
110 auto obj = _refs.find(path);
111 if(obj != _refs.end())
112 throw std::runtime_error(
113 obj->first + " already exists");
114
115 // Create an interface holder for each interface
116 // provided by the client and group them into
117 // a container.
118 InterfaceComposite ref;
119
120 for (auto &x: object) {
Brad Bishop5fbaa7f2016-10-31 10:42:41 -0500121 auto maker = _makers.find(x.first.c_str());
Brad Bishop49aefb32016-10-19 11:54:14 -0400122
Brad Bishop5fbaa7f2016-10-31 10:42:41 -0500123 if(maker == _makers.end())
Brad Bishop49aefb32016-10-19 11:54:14 -0400124 throw std::runtime_error(
125 "Unimplemented interface: " + x.first);
126
127 ref.emplace(
128 std::make_pair(
129 x.first,
130 (maker->second)(_bus, path.c_str())));
131 }
132
133 // Hang on to a reference to the object (interfaces)
134 // so it stays on the bus, and so we can make calls
135 // to it if needed.
136 _refs.emplace(
137 std::make_pair(
138 path, std::move(ref)));
139 }
140 catch (const std::exception &e) {
141 std::cerr << e.what() << std::endl;
142 }
143}
144
145void Manager::signal(sdbusplus::message::message &msg, auto &args)
146{
Brad Bishop3d57f502016-10-19 12:18:41 -0400147 auto &filter = std::get<1>(args);
Brad Bishopc038e012016-10-19 13:02:24 -0400148 auto &action = std::get<2>(args);
Brad Bishop3d57f502016-10-19 12:18:41 -0400149
Brad Bishopc0eae112016-10-19 21:59:47 -0400150 if(filter(msg, *this)) {
151 action(*this);
Brad Bishop3d57f502016-10-19 12:18:41 -0400152 }
Brad Bishop49aefb32016-10-19 11:54:14 -0400153}
154
Brad Bishop656a7d02016-10-19 22:20:02 -0400155void Manager::destroyObject(const char *path)
156{
157 std::string p{path};
158 _refs.erase(_root + p);
159}
160
Brad Bishop49aefb32016-10-19 11:54:14 -0400161} // namespace manager
162} // namespace inventory
163} // namespace phosphor
164
165// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4